@observertc/observer-js 0.42.8 → 1.0.0-beta.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 (299) hide show
  1. package/.prettierrc +6 -6
  2. package/README.md +493 -63
  3. package/lib/ObservedCall.d.ts +63 -43
  4. package/lib/ObservedCall.d.ts.map +1 -1
  5. package/lib/ObservedCall.js +188 -108
  6. package/lib/ObservedCallEventMonitor.d.ts +104 -0
  7. package/lib/ObservedCallEventMonitor.d.ts.map +1 -0
  8. package/lib/ObservedCallEventMonitor.js +314 -0
  9. package/lib/ObservedCallSummary.d.ts +18 -0
  10. package/lib/ObservedCallSummary.d.ts.map +1 -0
  11. package/lib/ObservedCertificate.d.ts +19 -0
  12. package/lib/ObservedCertificate.d.ts.map +1 -0
  13. package/lib/ObservedCertificate.js +38 -0
  14. package/lib/ObservedClient.d.ts +81 -136
  15. package/lib/ObservedClient.d.ts.map +1 -1
  16. package/lib/ObservedClient.js +581 -744
  17. package/lib/ObservedClientEventMonitor.d.ts +91 -0
  18. package/lib/ObservedClientEventMonitor.d.ts.map +1 -0
  19. package/lib/ObservedClientEventMonitor.js +254 -0
  20. package/lib/ObservedClientSummary.d.ts +23 -0
  21. package/lib/ObservedClientSummary.d.ts.map +1 -0
  22. package/lib/ObservedClientSummary.js +2 -0
  23. package/lib/ObservedCodec.d.ts +22 -0
  24. package/lib/ObservedCodec.d.ts.map +1 -0
  25. package/lib/ObservedCodec.js +45 -0
  26. package/lib/ObservedDataChannel.d.ts +25 -69
  27. package/lib/ObservedDataChannel.d.ts.map +1 -1
  28. package/lib/ObservedDataChannel.js +69 -109
  29. package/lib/ObservedIceCandidate.d.ts +29 -0
  30. package/lib/ObservedIceCandidate.d.ts.map +1 -0
  31. package/lib/ObservedIceCandidate.js +59 -0
  32. package/lib/ObservedIceCandidatePair.d.ts +45 -0
  33. package/lib/ObservedIceCandidatePair.d.ts.map +1 -0
  34. package/lib/ObservedIceCandidatePair.js +127 -0
  35. package/lib/ObservedIceTransport.d.ts +36 -0
  36. package/lib/ObservedIceTransport.d.ts.map +1 -0
  37. package/lib/ObservedIceTransport.js +93 -0
  38. package/lib/ObservedInboundRtp.d.ts +92 -0
  39. package/lib/ObservedInboundRtp.d.ts.map +1 -0
  40. package/lib/ObservedInboundRtp.js +193 -0
  41. package/lib/ObservedInboundTrack.d.ts +32 -0
  42. package/lib/ObservedInboundTrack.d.ts.map +1 -0
  43. package/lib/ObservedInboundTrack.js +60 -0
  44. package/lib/ObservedMediaPlayout.d.ts +22 -0
  45. package/lib/ObservedMediaPlayout.d.ts.map +1 -0
  46. package/lib/ObservedMediaPlayout.js +42 -0
  47. package/lib/ObservedMediaSource.d.ts +28 -0
  48. package/lib/ObservedMediaSource.d.ts.map +1 -0
  49. package/lib/ObservedMediaSource.js +55 -0
  50. package/lib/ObservedOutboundRtp.d.ts +62 -0
  51. package/lib/ObservedOutboundRtp.d.ts.map +1 -0
  52. package/lib/ObservedOutboundRtp.js +144 -0
  53. package/lib/ObservedOutboundTrack.d.ts +32 -0
  54. package/lib/ObservedOutboundTrack.d.ts.map +1 -0
  55. package/lib/ObservedOutboundTrack.js +60 -0
  56. package/lib/ObservedPeerConnection.d.ts +154 -80
  57. package/lib/ObservedPeerConnection.d.ts.map +1 -1
  58. package/lib/ObservedPeerConnection.js +709 -357
  59. package/lib/ObservedPeerConnectionTransport.d.ts +17 -0
  60. package/lib/ObservedPeerConnectionTransport.d.ts.map +1 -0
  61. package/lib/ObservedPeerConnectionTransport.js +34 -0
  62. package/lib/ObservedRemoteInboundRtp.d.ts +30 -0
  63. package/lib/ObservedRemoteInboundRtp.d.ts.map +1 -0
  64. package/lib/ObservedRemoteInboundRtp.js +60 -0
  65. package/lib/ObservedRemoteOutboundRtp.d.ts +30 -0
  66. package/lib/ObservedRemoteOutboundRtp.d.ts.map +1 -0
  67. package/lib/ObservedRemoteOutboundRtp.js +60 -0
  68. package/lib/ObservedTURN.d.ts +31 -0
  69. package/lib/ObservedTURN.d.ts.map +1 -0
  70. package/lib/ObservedTURN.js +58 -0
  71. package/lib/ObservedTurnServer.d.ts +25 -0
  72. package/lib/ObservedTurnServer.d.ts.map +1 -0
  73. package/lib/ObservedTurnServer.js +59 -0
  74. package/lib/Observer.d.ts +49 -54
  75. package/lib/Observer.d.ts.map +1 -1
  76. package/lib/Observer.js +131 -226
  77. package/lib/ObserverEventMonitor.d.ts +138 -0
  78. package/lib/ObserverEventMonitor.d.ts.map +1 -0
  79. package/lib/ObserverEventMonitor.js +433 -0
  80. package/lib/ObserverSummary.d.ts +13 -0
  81. package/lib/ObserverSummary.d.ts.map +1 -0
  82. package/lib/ObserverSummary.js +2 -0
  83. package/lib/common/Middleware.d.ts +10 -1
  84. package/lib/common/Middleware.d.ts.map +1 -1
  85. package/lib/common/Middleware.js +55 -36
  86. package/lib/common/logger.d.ts +8 -4
  87. package/lib/common/logger.d.ts.map +1 -1
  88. package/lib/common/logger.js +44 -68
  89. package/lib/common/types.d.ts +0 -21
  90. package/lib/common/types.d.ts.map +1 -1
  91. package/lib/common/types.js +1 -0
  92. package/lib/common/utils.d.ts +3 -1
  93. package/lib/common/utils.d.ts.map +1 -1
  94. package/lib/common/utils.js +23 -3
  95. package/lib/detectors/Detector.d.ts +5 -0
  96. package/lib/detectors/Detector.d.ts.map +1 -0
  97. package/lib/detectors/Detector.js +3 -0
  98. package/lib/detectors/Detectors.d.ts +11 -0
  99. package/lib/detectors/Detectors.d.ts.map +1 -0
  100. package/lib/detectors/Detectors.js +34 -0
  101. package/lib/index.d.ts +26 -24
  102. package/lib/index.d.ts.map +1 -1
  103. package/lib/index.js +45 -41
  104. package/lib/mediasoup/ObservedMediaRouter.d.ts +10 -0
  105. package/lib/mediasoup/ObservedMediaRouter.d.ts.map +1 -0
  106. package/lib/mediasoup/ObservedMediaRouter.js +6 -0
  107. package/lib/monitors/TurnUsageMonitor.d.ts +0 -52
  108. package/lib/monitors/TurnUsageMonitor.d.ts.map +1 -1
  109. package/lib/monitors/TurnUsageMonitor.js +145 -120
  110. package/lib/schema/ClientEventTypes.d.ts +228 -0
  111. package/lib/schema/ClientEventTypes.d.ts.map +1 -0
  112. package/lib/schema/ClientEventTypes.js +41 -0
  113. package/lib/schema/ClientMetaTypes.d.ts +34 -0
  114. package/lib/schema/ClientMetaTypes.d.ts.map +1 -0
  115. package/lib/schema/ClientMetaTypes.js +16 -0
  116. package/lib/schema/ClientSample.d.ts +1333 -0
  117. package/lib/schema/ClientSample.d.ts.map +1 -0
  118. package/lib/schema/ClientSample.js +4 -0
  119. package/lib/scores/CalculatedScore.d.ts +6 -0
  120. package/lib/scores/CalculatedScore.d.ts.map +1 -0
  121. package/lib/scores/CalculatedScore.js +2 -0
  122. package/lib/scores/DefaultCallScoreCalculator.d.ts +7 -0
  123. package/lib/scores/DefaultCallScoreCalculator.d.ts.map +1 -0
  124. package/lib/scores/DefaultCallScoreCalculator.js +21 -0
  125. package/lib/scores/ScoreCalculator.d.ts +4 -0
  126. package/lib/scores/ScoreCalculator.d.ts.map +1 -0
  127. package/lib/scores/ScoreCalculator.js +2 -0
  128. package/lib/updaters/CallUpdater.d.ts +5 -0
  129. package/lib/updaters/CallUpdater.d.ts.map +1 -0
  130. package/lib/updaters/CallUpdater.js +2 -0
  131. package/lib/updaters/ObserverUpdater.d.ts +5 -0
  132. package/lib/updaters/ObserverUpdater.d.ts.map +1 -0
  133. package/lib/updaters/ObserverUpdater.js +2 -0
  134. package/lib/updaters/OnAllCallObserverUpdater.d.ts +15 -0
  135. package/lib/updaters/OnAllCallObserverUpdater.d.ts.map +1 -0
  136. package/lib/updaters/OnAllCallObserverUpdater.js +50 -0
  137. package/lib/updaters/OnAllClientCallUpdater.d.ts +15 -0
  138. package/lib/updaters/OnAllClientCallUpdater.d.ts.map +1 -0
  139. package/lib/updaters/OnAllClientCallUpdater.js +53 -0
  140. package/lib/updaters/OnAnyCallObserverUpdater.d.ts +12 -0
  141. package/lib/updaters/OnAnyCallObserverUpdater.d.ts.map +1 -0
  142. package/lib/updaters/OnAnyCallObserverUpdater.js +37 -0
  143. package/lib/updaters/OnAnyClientCallUpdater.d.ts +12 -0
  144. package/lib/updaters/OnAnyClientCallUpdater.d.ts.map +1 -0
  145. package/lib/updaters/OnAnyClientCallUpdater.js +36 -0
  146. package/lib/updaters/OnIntervalUpdater.d.ts +10 -0
  147. package/lib/updaters/OnIntervalUpdater.d.ts.map +1 -0
  148. package/lib/updaters/OnIntervalUpdater.js +17 -0
  149. package/lib/updaters/Updater.d.ts +6 -0
  150. package/lib/updaters/Updater.d.ts.map +1 -0
  151. package/lib/updaters/Updater.js +2 -0
  152. package/lib/utils/MediasoupRemoteTrackResolver.d.ts +25 -0
  153. package/lib/utils/MediasoupRemoteTrackResolver.d.ts.map +1 -0
  154. package/lib/utils/MediasoupRemoteTrackResolver.js +110 -0
  155. package/lib/utils/RemoteTrackResolver.d.ts +7 -0
  156. package/lib/utils/RemoteTrackResolver.d.ts.map +1 -0
  157. package/lib/utils/RemoteTrackResolver.js +2 -0
  158. package/package.json +4 -4
  159. package/src/ObservedCall.ts +276 -164
  160. package/src/ObservedCallEventMonitor.ts +392 -0
  161. package/src/ObservedCallSummary.ts +22 -0
  162. package/src/ObservedCertificate.ts +43 -0
  163. package/src/ObservedClient.ts +625 -1006
  164. package/src/ObservedClientEventMonitor.ts +309 -0
  165. package/src/ObservedClientSummary.ts +24 -0
  166. package/src/ObservedCodec.ts +49 -0
  167. package/src/ObservedDataChannel.ts +71 -181
  168. package/src/ObservedIceCandidate.ts +64 -0
  169. package/src/ObservedIceCandidatePair.ts +134 -0
  170. package/src/ObservedIceTransport.ts +99 -0
  171. package/src/ObservedInboundRtp.ts +205 -0
  172. package/src/ObservedInboundTrack.ts +75 -0
  173. package/src/ObservedMediaPlayout.ts +49 -0
  174. package/src/ObservedMediaSource.ts +60 -0
  175. package/src/ObservedOutboundRtp.ts +156 -0
  176. package/src/ObservedOutboundTrack.ts +74 -0
  177. package/src/ObservedPeerConnection.ts +917 -402
  178. package/src/ObservedPeerConnectionTransport.ts +38 -0
  179. package/src/ObservedRemoteInboundRtp.ts +64 -0
  180. package/src/ObservedRemoteOutboundRtp.ts +65 -0
  181. package/src/ObservedTURN.ts +86 -0
  182. package/src/ObservedTurnServer.ts +72 -0
  183. package/src/Observer.ts +182 -298
  184. package/src/ObserverEventMonitor.ts +551 -0
  185. package/src/ObserverSummary.ts +15 -0
  186. package/src/common/Middleware.ts +70 -42
  187. package/src/common/logger.ts +60 -69
  188. package/src/common/types.ts +0 -42
  189. package/src/common/utils.ts +24 -2
  190. package/src/detectors/Detector.ts +6 -0
  191. package/src/detectors/Detectors.ts +38 -0
  192. package/src/index.ts +26 -88
  193. package/src/mediasoup/ObservedMediaRouter.ts +10 -0
  194. package/src/monitors/TurnUsageMonitor.ts +164 -164
  195. package/src/schema/ClientEventTypes.ts +280 -0
  196. package/src/schema/ClientMetaTypes.ts +41 -0
  197. package/src/schema/ClientSample.ts +1682 -0
  198. package/src/scores/CalculatedScore.ts +6 -0
  199. package/src/scores/DefaultCallScoreCalculator.ts +23 -0
  200. package/src/scores/ScoreCalculator.ts +3 -0
  201. package/src/updaters/CallUpdater.ts +5 -0
  202. package/src/updaters/ObserverUpdater.ts +5 -0
  203. package/src/updaters/OnAllCallObserverUpdater.ts +59 -0
  204. package/src/updaters/OnAllClientCallUpdater.ts +61 -0
  205. package/src/updaters/OnAnyCallObserverUpdater.ts +41 -0
  206. package/src/updaters/OnAnyClientCallUpdater.ts +39 -0
  207. package/src/updaters/OnIntervalUpdater.ts +19 -0
  208. package/src/updaters/Updater.ts +5 -0
  209. package/src/utils/MediasoupRemoteTrackResolver.ts +155 -0
  210. package/src/utils/RemoteTrackResolver.ts +12 -0
  211. package/tsconfig.json +3 -3
  212. package/lib/ObservedICE.d.ts +0 -64
  213. package/lib/ObservedICE.d.ts.map +0 -1
  214. package/lib/ObservedICE.js +0 -141
  215. package/lib/ObservedInboundAudioTrack.d.ts +0 -96
  216. package/lib/ObservedInboundAudioTrack.d.ts.map +0 -1
  217. package/lib/ObservedInboundAudioTrack.js +0 -217
  218. package/lib/ObservedInboundVideoTrack.d.ts +0 -101
  219. package/lib/ObservedInboundVideoTrack.d.ts.map +0 -1
  220. package/lib/ObservedInboundVideoTrack.js +0 -232
  221. package/lib/ObservedOutboundAudioTrack.d.ts +0 -87
  222. package/lib/ObservedOutboundAudioTrack.d.ts.map +0 -1
  223. package/lib/ObservedOutboundAudioTrack.js +0 -186
  224. package/lib/ObservedOutboundVideoTrack.d.ts +0 -91
  225. package/lib/ObservedOutboundVideoTrack.d.ts.map +0 -1
  226. package/lib/ObservedOutboundVideoTrack.js +0 -193
  227. package/lib/ObservedSfu.d.ts +0 -59
  228. package/lib/ObservedSfu.d.ts.map +0 -1
  229. package/lib/ObservedSfu.js +0 -157
  230. package/lib/ObservedSfuInboundRtpPad.d.ts +0 -42
  231. package/lib/ObservedSfuInboundRtpPad.d.ts.map +0 -1
  232. package/lib/ObservedSfuInboundRtpPad.js +0 -71
  233. package/lib/ObservedSfuOutboundRtpPad.d.ts +0 -42
  234. package/lib/ObservedSfuOutboundRtpPad.d.ts.map +0 -1
  235. package/lib/ObservedSfuOutboundRtpPad.js +0 -72
  236. package/lib/ObservedSfuSctpChannel.d.ts +0 -42
  237. package/lib/ObservedSfuSctpChannel.d.ts.map +0 -1
  238. package/lib/ObservedSfuSctpChannel.js +0 -57
  239. package/lib/ObservedSfuTransport.d.ts +0 -58
  240. package/lib/ObservedSfuTransport.d.ts.map +0 -1
  241. package/lib/ObservedSfuTransport.js +0 -120
  242. package/lib/RemoteTrackAssigner.d.ts +0 -14
  243. package/lib/RemoteTrackAssigner.d.ts.map +0 -1
  244. package/lib/RemoteTrackAssigner.js +0 -52
  245. package/lib/ReportsCollector.d.ts +0 -109
  246. package/lib/ReportsCollector.d.ts.map +0 -1
  247. package/lib/ReportsCollector.js +0 -207
  248. package/lib/common/CalculatedScore.d.ts +0 -80
  249. package/lib/common/CalculatedScore.d.ts.map +0 -1
  250. package/lib/common/CalculatedScore.js +0 -162
  251. package/lib/common/CallEventType.d.ts +0 -63
  252. package/lib/common/CallEventType.d.ts.map +0 -1
  253. package/lib/common/CallEventType.js +0 -39
  254. package/lib/common/CallMetaReports.d.ts +0 -42
  255. package/lib/common/CallMetaReports.d.ts.map +0 -1
  256. package/lib/common/CallMetaReports.js +0 -36
  257. package/lib/common/QualityScoreUtils.d.ts +0 -1
  258. package/lib/common/QualityScoreUtils.d.ts.map +0 -1
  259. package/lib/common/QualityScoreUtils.js +0 -1
  260. package/lib/common/TypedEventEmitter.d.ts +0 -22
  261. package/lib/common/TypedEventEmitter.d.ts.map +0 -1
  262. package/lib/common/TypedEventEmitter.js +0 -11
  263. package/lib/common/callEventReports.d.ts +0 -10
  264. package/lib/common/callEventReports.d.ts.map +0 -1
  265. package/lib/common/callEventReports.js +0 -112
  266. package/lib/monitors/CallSummary.d.ts +0 -37
  267. package/lib/monitors/CallSummary.d.ts.map +0 -1
  268. package/lib/monitors/CallSummaryMonitor.d.ts +0 -32
  269. package/lib/monitors/CallSummaryMonitor.d.ts.map +0 -1
  270. package/lib/monitors/CallSummaryMonitor.js +0 -152
  271. package/lib/monitors/ClientIssueMonitor.d.ts +0 -32
  272. package/lib/monitors/ClientIssueMonitor.d.ts.map +0 -1
  273. package/lib/monitors/ClientIssueMonitor.js +0 -49
  274. package/lib/monitors/SfuServerMonitor.d.ts +0 -79
  275. package/lib/monitors/SfuServerMonitor.d.ts.map +0 -1
  276. package/lib/monitors/SfuServerMonitor.js +0 -198
  277. package/src/ObservedICE.ts +0 -237
  278. package/src/ObservedInboundAudioTrack.ts +0 -344
  279. package/src/ObservedInboundVideoTrack.ts +0 -361
  280. package/src/ObservedOutboundAudioTrack.ts +0 -307
  281. package/src/ObservedOutboundVideoTrack.ts +0 -319
  282. package/src/ObservedSfu.ts +0 -231
  283. package/src/ObservedSfuInboundRtpPad.ts +0 -106
  284. package/src/ObservedSfuOutboundRtpPad.ts +0 -107
  285. package/src/ObservedSfuSctpChannel.ts +0 -103
  286. package/src/ObservedSfuTransport.ts +0 -185
  287. package/src/RemoteTrackAssigner.ts +0 -68
  288. package/src/ReportsCollector.ts +0 -336
  289. package/src/common/CalculatedScore.ts +0 -188
  290. package/src/common/CallEventType.ts +0 -69
  291. package/src/common/CallMetaReports.ts +0 -82
  292. package/src/common/QualityScoreUtils.ts +0 -0
  293. package/src/common/TypedEventEmitter.ts +0 -32
  294. package/src/common/callEventReports.ts +0 -178
  295. package/src/monitors/CallSummary.ts +0 -38
  296. package/src/monitors/CallSummaryMonitor.ts +0 -192
  297. package/src/monitors/ClientIssueMonitor.ts +0 -88
  298. package/src/monitors/SfuServerMonitor.ts +0 -285
  299. /package/lib/{monitors/CallSummary.js → ObservedCallSummary.js} +0 -0
@@ -2,169 +2,194 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ObservedPeerConnection = void 0;
4
4
  const events_1 = require("events");
5
- const ObservedICE_1 = require("./ObservedICE");
5
+ const ObservedInboundRtp_1 = require("./ObservedInboundRtp");
6
+ const logger_1 = require("./common/logger");
7
+ const ObservedOutboundRtp_1 = require("./ObservedOutboundRtp");
8
+ const ObservedCertificate_1 = require("./ObservedCertificate");
9
+ const ObservedCodec_1 = require("./ObservedCodec");
6
10
  const ObservedDataChannel_1 = require("./ObservedDataChannel");
7
- const ObservedInboundAudioTrack_1 = require("./ObservedInboundAudioTrack");
8
- const ObservedInboundVideoTrack_1 = require("./ObservedInboundVideoTrack");
9
- const ObservedOutboundAudioTrack_1 = require("./ObservedOutboundAudioTrack");
10
- const ObservedOutboundVideoTrack_1 = require("./ObservedOutboundVideoTrack");
11
- const CalculatedScore_1 = require("./common/CalculatedScore");
11
+ const ObservedIceCandidate_1 = require("./ObservedIceCandidate");
12
+ const ObservedIceCandidatePair_1 = require("./ObservedIceCandidatePair");
13
+ const ObservedIceTransport_1 = require("./ObservedIceTransport");
14
+ const ObservedMediaSource_1 = require("./ObservedMediaSource");
15
+ const ObservedPeerConnectionTransport_1 = require("./ObservedPeerConnectionTransport");
16
+ const ObservedMediaPlayout_1 = require("./ObservedMediaPlayout");
17
+ const ObservedRemoteInboundRtp_1 = require("./ObservedRemoteInboundRtp");
18
+ const ObservedRemoteOutboundRtp_1 = require("./ObservedRemoteOutboundRtp");
19
+ const ObservedInboundTrack_1 = require("./ObservedInboundTrack");
20
+ const ObservedOutboundTrack_1 = require("./ObservedOutboundTrack");
21
+ const utils_1 = require("./common/utils");
22
+ const logger = (0, logger_1.createLogger)('ObservedPeerConnection');
12
23
  class ObservedPeerConnection extends events_1.EventEmitter {
13
- constructor(_model, client) {
24
+ peerConnectionId;
25
+ client;
26
+ _visited = true;
27
+ appData;
28
+ calculatedScore = {
29
+ weight: 1,
30
+ value: undefined,
31
+ };
32
+ closed = false;
33
+ // timestamp of the PEER_CONNECTION_OPENED event
34
+ openedAt;
35
+ // timestamp of the PEER_CONNECTION_CLOSED event
36
+ closedAt;
37
+ updated = Date.now();
38
+ connectionState;
39
+ iceConnectionState;
40
+ iceGatheringState;
41
+ availableIncomingBitrate = 0;
42
+ availableOutgoingBitrate = 0;
43
+ totalInboundPacketsLost = 0;
44
+ totalInboundPacketsReceived = 0;
45
+ totalOutboundPacketsSent = 0;
46
+ totalDataChannelBytesSent = 0;
47
+ totalDataChannelBytesReceived = 0;
48
+ totalDataChannelMessagesSent = 0;
49
+ totalDataChannelMessagesReceived = 0;
50
+ totalSentAudioBytes = 0;
51
+ totalSentVideoBytes = 0;
52
+ totalSentAudioPackets = 0;
53
+ totalSentVideoPackets = 0;
54
+ totalReceivedAudioPacktes = 0;
55
+ totalReceivedVideoPackets = 0;
56
+ totalReceivedAudioBytes = 0;
57
+ totalReceivedVideoBytes = 0;
58
+ deltaInboundPacketsLost = 0;
59
+ deltaInboundPacketsReceived = 0;
60
+ deltaOutboundPacketsSent = 0;
61
+ deltaDataChannelBytesSent = 0;
62
+ deltaDataChannelBytesReceived = 0;
63
+ deltaDataChannelMessagesSent = 0;
64
+ deltaDataChannelMessagesReceived = 0;
65
+ deltaInboundReceivedBytes = 0;
66
+ deltaOutboundSentBytes = 0;
67
+ deltaReceivedAudioBytes = 0;
68
+ deltaReceivedVideoBytes = 0;
69
+ deltaReceivedAudioPackets = 0;
70
+ deltaReceivedVideoPackets = 0;
71
+ deltaSentAudioBytes = 0;
72
+ deltaSentVideoBytes = 0;
73
+ deltaTransportSentBytes = 0;
74
+ deltaTransportReceivedBytes = 0;
75
+ receivingPacketsPerSecond = 0;
76
+ sendingPacketsPerSecond = 0;
77
+ sendingAudioBitrate = 0;
78
+ sendingVideoBitrate = 0;
79
+ receivingAudioBitrate = 0;
80
+ receivingVideoBitrate = 0;
81
+ currentRttInMs;
82
+ currentJitter;
83
+ usingTCP = false;
84
+ usingTURN = false;
85
+ observedTurnServer;
86
+ observedCertificates = new Map();
87
+ observedCodecs = new Map();
88
+ observedDataChannels = new Map();
89
+ observedIceCandidates = new Map();
90
+ observedIceCandidatesPair = new Map();
91
+ observedIceTransports = new Map();
92
+ observedInboundRtps = new Map();
93
+ observedInboundTracks = new Map();
94
+ observedMediaPlayouts = new Map();
95
+ observedMediaSources = new Map();
96
+ observedOutboundRtps = new Map();
97
+ observedOutboundTracks = new Map();
98
+ observedPeerConnectionTransports = new Map();
99
+ observedRemoteInboundRtps = new Map();
100
+ observedRemoteOutboundRtps = new Map();
101
+ constructor(peerConnectionId, client) {
14
102
  super();
15
- this._model = _model;
103
+ this.peerConnectionId = peerConnectionId;
16
104
  this.client = client;
17
- this.created = Date.now();
18
- this.visited = true;
19
- this._stabilityScores = [];
20
- this.ωpendingIssuesForScores = [];
21
- this.totalInboundPacketsLost = 0;
22
- this.totalInboundPacketsReceived = 0;
23
- this.totalOutboundPacketsSent = 0;
24
- this.totalDataChannelBytesSent = 0;
25
- this.totalDataChannelBytesReceived = 0;
26
- this.totalSentAudioBytes = 0;
27
- this.totalSentVideoBytes = 0;
28
- this.totalSentAudioPackets = 0;
29
- this.totalSentVideoPackets = 0;
30
- this.totalReceivedAudioPacktes = 0;
31
- this.totalReceivedVideoPackets = 0;
32
- this.totalReceivedAudioBytes = 0;
33
- this.totalReceivedVideoBytes = 0;
34
- this.deltaInboundPacketsLost = 0;
35
- this.deltaInboundPacketsReceived = 0;
36
- this.deltaOutboundPacketsSent = 0;
37
- this.deltaDataChannelBytesSent = 0;
38
- this.deltaDataChannelBytesReceived = 0;
39
- this.deltaInboundReceivedBytes = 0;
40
- this.deltaOutboundSentBytes = 0;
41
- this.deltaReceivedAudioBytes = 0;
42
- this.deltaReceivedVideoBytes = 0;
43
- this.deltaReceivedAudioPackets = 0;
44
- this.deltaReceivedVideoPackets = 0;
45
- this.deltaSentAudioBytes = 0;
46
- this.deltaSentVideoBytes = 0;
47
- this.receivingPacketsPerSecond = 0;
48
- this.sendingPacketsPerSecond = 0;
49
- this.sendingAudioBitrate = 0;
50
- this.sendingVideoBitrate = 0;
51
- this.receivingAudioBitrate = 0;
52
- this.receivingVideoBitrate = 0;
53
- this._closed = false;
54
- this._updated = Date.now();
55
- this.ICE = ObservedICE_1.ObservedICE.create(this);
56
- this._inboundAudioTracks = new Map();
57
- this._inboundVideoTracks = new Map();
58
- this._outboundAudioTracks = new Map();
59
- this._outboundVideoTracks = new Map();
60
- this._dataChannels = new Map();
61
105
  this.setMaxListeners(Infinity);
62
106
  }
63
- get serviceId() {
64
- return this.client.serviceId;
65
- }
66
- get roomId() {
67
- return this.client.roomId;
68
- }
69
- get callId() {
70
- return this.client.callId;
71
- }
72
- get clientId() {
73
- return this.client.clientId;
107
+ get score() {
108
+ return this.calculatedScore.value;
74
109
  }
75
- get mediaUnitId() {
76
- return this.client.mediaUnitId;
110
+ get visited() {
111
+ const visited = this._visited;
112
+ this._visited = false;
113
+ return visited;
77
114
  }
78
- get label() {
79
- return this._model.label;
115
+ get codecs() {
116
+ return [...this.observedCodecs.values()];
80
117
  }
81
- set label(value) {
82
- this._model.label = value;
118
+ get inboundRtps() {
119
+ return [...this.observedInboundRtps.values()];
83
120
  }
84
- get usingTURN() {
85
- return this.ICE.usingTURN;
121
+ get remoteOutboundRtps() {
122
+ return [...this.observedRemoteOutboundRtps.values()];
86
123
  }
87
- get availableOutgoingBitrate() {
88
- var _a;
89
- return (_a = this.ICE.stats) === null || _a === void 0 ? void 0 : _a.availableOutgoingBitrate;
124
+ get outboundRtps() {
125
+ return [...this.observedOutboundRtps.values()];
90
126
  }
91
- get availableIncomingBitrate() {
92
- var _a;
93
- return (_a = this.ICE.stats) === null || _a === void 0 ? void 0 : _a.availableIncomingBitrate;
127
+ get remoteInboundRtps() {
128
+ return [...this.observedRemoteInboundRtps.values()];
94
129
  }
95
- get peerConnectionId() {
96
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
97
- return this._model.peerConnectionId;
130
+ get mediaSources() {
131
+ return [...this.observedMediaSources.values()];
98
132
  }
99
- get reports() {
100
- return this.client.reports;
133
+ get mediaPlayouts() {
134
+ return [...this.observedMediaPlayouts.values()];
101
135
  }
102
- get stats() {
103
- return this._sample;
104
- }
105
- get updated() {
106
- return this._updated;
107
- }
108
- get inboundAudioTracks() {
109
- return this._inboundAudioTracks;
110
- }
111
- get inboundVideoTracks() {
112
- return this._inboundVideoTracks;
113
- }
114
- get outboundAudioTracks() {
115
- return this._outboundAudioTracks;
136
+ get dataChannels() {
137
+ return [...this.observedDataChannels.values()];
116
138
  }
117
- get outboundVideoTracks() {
118
- return this._outboundVideoTracks;
139
+ get peerConnectionTransports() {
140
+ return [...this.observedPeerConnectionTransports.values()];
119
141
  }
120
- get dataChannels() {
121
- return this._dataChannels;
142
+ get iceTransports() {
143
+ return [...this.observedIceTransports.values()];
122
144
  }
123
- get uptimeInMs() {
124
- return this._updated - this.created;
145
+ get iceCandidates() {
146
+ return [...this.observedIceCandidates.values()];
125
147
  }
126
- get marker() {
127
- return this._marker;
148
+ get iceCandidatePairs() {
149
+ return [...this.observedIceCandidatesPair.values()];
128
150
  }
129
- set marker(value) {
130
- this._marker = value;
131
- this._inboundAudioTracks.forEach((track) => (track.marker = value));
132
- this._inboundVideoTracks.forEach((track) => (track.marker = value));
133
- this._outboundAudioTracks.forEach((track) => (track.marker = value));
134
- this._outboundVideoTracks.forEach((track) => (track.marker = value));
135
- this._dataChannels.forEach((channel) => (channel.marker = value));
136
- this.ICE.marker = value;
151
+ get certificates() {
152
+ return [...this.observedCertificates.values()];
137
153
  }
138
- addEventReport(params) {
139
- var _a;
140
- this.reports.addCallEventReport(Object.assign(Object.assign({}, params), { serviceId: this.serviceId, mediaUnitId: this.mediaUnitId, roomId: this.roomId, callId: this.callId, clientId: this.clientId, userId: this.client.userId, peerConnectionId: this.peerConnectionId, marker: this.client.marker, timestamp: (_a = params.timestamp) !== null && _a !== void 0 ? _a : Date.now() }));
154
+ get selectedIceCandidatePairs() {
155
+ return this.iceTransports.map((iceTransport) => iceTransport.getSelectedCandidatePair())
156
+ .filter((pair) => pair !== undefined);
141
157
  }
142
- get closed() {
143
- return this._closed;
158
+ get selectedIceCandiadtePairForTurn() {
159
+ return this.selectedIceCandidatePairs
160
+ .filter((pair) => pair.getLocalCandidate()?.candidateType === 'relay' &&
161
+ pair.getRemoteCandidate()?.url?.startsWith('turn:'));
144
162
  }
145
163
  close() {
146
- if (this._closed)
164
+ if (this.closed)
147
165
  return;
148
- this._closed = true;
149
- Array.from(this._inboundAudioTracks.values()).forEach((track) => track.close());
150
- Array.from(this._inboundVideoTracks.values()).forEach((track) => track.close());
151
- Array.from(this._outboundAudioTracks.values()).forEach((track) => {
152
- var _a;
153
- this.client.call.sfuStreamIdToOutboundAudioTrack.delete((_a = track.sfuStreamId) !== null && _a !== void 0 ? _a : '');
154
- track.close();
155
- });
156
- Array.from(this._outboundVideoTracks.values()).forEach((track) => {
157
- var _a;
158
- this.client.call.sfuStreamIdToOutboundVideoTrack.delete((_a = track.sfuStreamId) !== null && _a !== void 0 ? _a : '');
159
- track.close();
160
- });
166
+ this.closed = true;
167
+ this.observedCertificates.clear();
168
+ this.observedCodecs.clear();
169
+ this.observedDataChannels.clear();
170
+ this.observedIceCandidates.clear();
171
+ this.observedIceCandidatesPair.clear();
172
+ this.observedIceTransports.clear();
173
+ this.observedInboundRtps.clear();
174
+ this.observedInboundTracks.clear();
175
+ this.observedMediaPlayouts.clear();
176
+ this.observedMediaSources.clear();
177
+ this.observedOutboundRtps.clear();
178
+ this.observedOutboundTracks.clear();
179
+ this.observedPeerConnectionTransports.clear();
180
+ this.observedRemoteInboundRtps.clear();
181
+ this.observedRemoteOutboundRtps.clear();
182
+ this.client.call.observer.observedTURN.removePeerConnection(this);
183
+ if (!this.closedAt)
184
+ this.closedAt = Date.now();
161
185
  this.emit('close');
162
186
  }
163
- getTrack(trackId) {
164
- var _a, _b, _c;
165
- return (_c = (_b = (_a = this._inboundAudioTracks.get(trackId)) !== null && _a !== void 0 ? _a : this._inboundVideoTracks.get(trackId)) !== null && _b !== void 0 ? _b : this._outboundAudioTracks.get(trackId)) !== null && _c !== void 0 ? _c : this._outboundVideoTracks.get(trackId);
166
- }
167
- resetMetrics() {
187
+ accept(sample) {
188
+ if (this.closed)
189
+ return;
190
+ this._visited = true;
191
+ this.availableIncomingBitrate = 0;
192
+ this.availableOutgoingBitrate = 0;
168
193
  this.deltaInboundPacketsLost = 0;
169
194
  this.deltaInboundPacketsReceived = 0;
170
195
  this.deltaOutboundPacketsSent = 0;
@@ -178,244 +203,571 @@ class ObservedPeerConnection extends events_1.EventEmitter {
178
203
  this.deltaReceivedVideoPackets = 0;
179
204
  this.deltaSentAudioBytes = 0;
180
205
  this.deltaSentVideoBytes = 0;
206
+ this.deltaTransportReceivedBytes = 0;
207
+ this.deltaTransportSentBytes = 0;
181
208
  this.sendingAudioBitrate = 0;
182
209
  this.sendingVideoBitrate = 0;
183
210
  this.receivingAudioBitrate = 0;
184
211
  this.receivingVideoBitrate = 0;
185
- this.ICE.resetMetrics();
186
- }
187
- update(sample, timestamp) {
188
- if (this._closed)
189
- return;
190
- if (sample.peerConnectionId !== this._model.peerConnectionId)
191
- throw new Error(`TransportId mismatch. PeerConnectionId: ${this._model.peerConnectionId} TransportId: ${sample.transportId}`);
192
- this._sample = sample;
193
- if (this._model.label !== sample.label) {
194
- this._model.label = sample.label;
195
- }
196
212
  const now = Date.now();
197
- const report = Object.assign(Object.assign({ serviceId: this.client.call.serviceId, roomId: this.client.call.roomId, callId: this.client.call.callId, clientId: this.client.clientId, userId: this.client.userId, mediaUnitId: this.client.mediaUnitId }, sample), { timestamp, sampleSeq: -1, marker: this.marker });
198
- this.reports.addPeerConnectionTransportReports(report);
199
- this._elapsedTimeSinceLastUpdate = now - this._updated;
200
- this.visited = true;
201
- this._updated = now;
202
- this._statsTimestamp = timestamp;
203
- this.emit('update', {
204
- elapsedTimeInMs: this._elapsedTimeSinceLastUpdate,
205
- });
206
- }
207
- createInboundAudioTrack(config) {
208
- if (this._closed)
209
- throw new Error(`PeerConnection ${this.peerConnectionId} is closed`);
210
- const result = new ObservedInboundAudioTrack_1.ObservedInboundAudioTrack(config, this);
211
- result.on('close', () => {
212
- this._inboundAudioTracks.delete(result.trackId);
213
- });
214
- this._inboundAudioTracks.set(result.trackId, result);
215
- this.emit('newinboudaudiotrack', result);
216
- return result;
217
- }
218
- createInboundVideoTrack(config) {
219
- if (this._closed)
220
- throw new Error(`PeerConnection ${this.peerConnectionId} is closed`);
221
- const result = new ObservedInboundVideoTrack_1.ObservedInboundVideoTrack(config, this);
222
- result.on('close', () => {
223
- this._inboundVideoTracks.delete(result.trackId);
224
- });
225
- this._inboundVideoTracks.set(result.trackId, result);
226
- this.emit('newinboudvideotrack', result);
227
- return result;
228
- }
229
- createOutboundAudioTrack(config) {
230
- if (this._closed)
231
- throw new Error(`PeerConnection ${this.peerConnectionId} is closed`);
232
- const result = new ObservedOutboundAudioTrack_1.ObservedOutboundAudioTrack(config, this);
233
- result.on('close', () => {
234
- this._outboundAudioTracks.delete(result.trackId);
235
- });
236
- this._outboundAudioTracks.set(result.trackId, result);
237
- this.emit('newoutboundaudiotrack', result);
238
- return result;
239
- }
240
- createOutboundVideoTrack(config) {
241
- if (this._closed)
242
- throw new Error(`PeerConnection ${this.peerConnectionId} is closed`);
243
- const result = new ObservedOutboundVideoTrack_1.ObservedOutboundVideoTrack(config, this);
244
- result.on('close', () => {
245
- this._outboundVideoTracks.delete(result.trackId);
246
- });
247
- this._outboundVideoTracks.set(result.trackId, result);
248
- this.emit('newoutboundvideotrack', result);
249
- return result;
250
- }
251
- createDataChannel(channelId) {
252
- if (this._closed)
253
- throw new Error(`PeerConnection ${this.peerConnectionId} is closed`);
254
- const result = new ObservedDataChannel_1.ObservedDataChannel({
255
- channelId,
256
- }, this);
257
- result.on('close', () => {
258
- this._dataChannels.delete(result.channelId);
259
- });
260
- this._dataChannels.set(result.channelId, result);
261
- this.emit('newdatachannel', result);
262
- return result;
263
- }
264
- updateMetrics() {
265
- var _a;
266
- let sumRttInMs = 0;
267
- let sumJitter = 0;
268
- const trackScores = [];
269
- this._inboundAudioTracks.forEach((track) => {
270
- var _a, _b;
271
- track.updateMetrics();
272
- this.deltaInboundPacketsLost += track.deltaLostPackets;
273
- this.deltaInboundPacketsReceived += track.deltaReceivedPackets;
274
- this.deltaInboundReceivedBytes += track.deltaBytesReceived;
275
- this.deltaReceivedAudioBytes += track.deltaBytesReceived;
276
- this.deltaReceivedAudioPackets += track.deltaReceivedPackets;
277
- this.receivingAudioBitrate += track.bitrate;
278
- sumRttInMs += ((_a = track.rttInMs) !== null && _a !== void 0 ? _a : 0);
279
- sumJitter += ((_b = track.jitter) !== null && _b !== void 0 ? _b : 0);
280
- track.score && trackScores.push(track.score);
281
- });
282
- this._inboundVideoTracks.forEach((track) => {
283
- var _a, _b;
284
- track.updateMetrics();
285
- this.deltaInboundPacketsLost += track.deltaLostPackets;
286
- this.deltaInboundPacketsReceived += track.deltaReceivedPackets;
287
- this.deltaInboundReceivedBytes += track.deltaBytesReceived;
288
- this.deltaReceivedVideoBytes += track.deltaBytesReceived;
289
- this.deltaReceivedVideoPackets += track.deltaReceivedPackets;
290
- this.receivingVideoBitrate += track.bitrate;
291
- sumRttInMs += ((_a = track.rttInMs) !== null && _a !== void 0 ? _a : 0);
292
- sumJitter += ((_b = track.jitter) !== null && _b !== void 0 ? _b : 0);
293
- track.score && trackScores.push(track.score);
294
- });
295
- this._outboundAudioTracks.forEach((track) => {
296
- var _a, _b;
297
- track.updateMetrics();
298
- this.deltaOutboundPacketsSent += track.deltaSentPackets;
299
- this.deltaOutboundSentBytes += track.deltaSentBytes;
300
- this.deltaSentAudioBytes += track.deltaSentBytes;
301
- this.deltaSentAudioBytes += track.deltaSentPackets;
302
- this.sendingAudioBitrate += track.bitrate;
303
- sumRttInMs += ((_a = track.rttInMs) !== null && _a !== void 0 ? _a : 0);
304
- sumJitter += ((_b = track.jitter) !== null && _b !== void 0 ? _b : 0);
305
- track.score && trackScores.push(track.score);
306
- });
307
- this._outboundVideoTracks.forEach((track) => {
308
- var _a, _b;
309
- track.updateMetrics();
310
- this.deltaOutboundPacketsSent += track.deltaSentPackets;
311
- this.deltaOutboundSentBytes += track.deltaSentBytes;
312
- this.deltaSentVideoBytes += track.deltaSentBytes;
313
- this.deltaSentVideoBytes += track.deltaSentPackets;
314
- this.sendingVideoBitrate += track.bitrate;
315
- sumRttInMs += ((_a = track.rttInMs) !== null && _a !== void 0 ? _a : 0);
316
- sumJitter += ((_b = track.jitter) !== null && _b !== void 0 ? _b : 0);
317
- track.score && trackScores.push(track.score);
318
- });
319
- this._dataChannels.forEach((channel) => {
320
- this.deltaDataChannelBytesSent += channel.deltaBytesSent;
321
- this.deltaDataChannelBytesReceived += channel.deltaBytesReceived;
322
- });
323
- const iceRttInMs = (_a = this.ICE.stats) === null || _a === void 0 ? void 0 : _a.currentRoundTripTime;
324
- let nrOfBelongings = this._inboundAudioTracks.size + this._inboundVideoTracks.size + this._outboundAudioTracks.size + this._outboundVideoTracks.size;
325
- this.avgJitter = 0 < nrOfBelongings ? sumJitter / nrOfBelongings : undefined;
326
- if (iceRttInMs) {
327
- sumRttInMs += iceRttInMs;
328
- nrOfBelongings += 1;
329
- }
330
- this.avgRttInMs = 0 < nrOfBelongings ? sumRttInMs / nrOfBelongings : undefined;
331
- this.totalDataChannelBytesReceived += this.deltaDataChannelBytesReceived;
332
- this.totalDataChannelBytesSent += this.deltaDataChannelBytesSent;
213
+ const elapsedTimeInMs = now - this.updated;
214
+ const elapsedTimeInSec = elapsedTimeInMs / 1000;
215
+ const rttMeasurementsInSec = [];
216
+ const jitterMeasurements = [];
217
+ if (sample.certificates) {
218
+ for (const certificate of sample.certificates) {
219
+ this._updateCertificateStats(certificate);
220
+ }
221
+ }
222
+ if (sample.codecs) {
223
+ for (const codec of sample.codecs) {
224
+ this._updateCodecStats(codec);
225
+ }
226
+ }
227
+ if (sample.dataChannels) {
228
+ for (const dataChannel of sample.dataChannels) {
229
+ const observedDataChannel = this._updateDataChannelStats(dataChannel);
230
+ if (!observedDataChannel)
231
+ continue;
232
+ this.deltaDataChannelBytesSent += observedDataChannel.deltaBytesSent;
233
+ this.deltaDataChannelBytesReceived += observedDataChannel.deltaBytesReceived;
234
+ this.deltaDataChannelMessagesSent += observedDataChannel.deltaMessagesSent;
235
+ this.deltaDataChannelMessagesReceived += observedDataChannel.deltaMessagesReceived;
236
+ }
237
+ }
238
+ if (sample.iceCandidates) {
239
+ for (const iceCandidate of sample.iceCandidates) {
240
+ this._updateIceCandidateStats(iceCandidate);
241
+ }
242
+ }
243
+ if (sample.iceCandidatePairs) {
244
+ for (const iceCandidatePair of sample.iceCandidatePairs) {
245
+ const observedCandidatePair = this._updateIceCandidatePairStats(iceCandidatePair);
246
+ if (!observedCandidatePair)
247
+ continue;
248
+ if (observedCandidatePair.currentRoundTripTime) {
249
+ rttMeasurementsInSec.push(observedCandidatePair.currentRoundTripTime);
250
+ }
251
+ if (observedCandidatePair.availableIncomingBitrate) {
252
+ this.availableIncomingBitrate += observedCandidatePair.availableIncomingBitrate;
253
+ }
254
+ if (observedCandidatePair.availableOutgoingBitrate) {
255
+ this.availableOutgoingBitrate += observedCandidatePair.availableOutgoingBitrate;
256
+ }
257
+ }
258
+ }
259
+ if (sample.iceTransports) {
260
+ for (const iceTransport of sample.iceTransports) {
261
+ const observedIceTransport = this._updateIceTransportStats(iceTransport);
262
+ if (!observedIceTransport)
263
+ return;
264
+ observedIceTransport.bytesReceived;
265
+ }
266
+ }
267
+ if (sample.inboundRtps) {
268
+ for (const inboundRtp of sample.inboundRtps) {
269
+ const observedInboundRtp = this._updateInboundRtpStats(inboundRtp);
270
+ if (!observedInboundRtp)
271
+ continue;
272
+ this.deltaInboundPacketsLost += observedInboundRtp.deltaLostPackets;
273
+ this.deltaInboundPacketsReceived += observedInboundRtp.deltaReceivedPackets;
274
+ this.deltaInboundReceivedBytes += observedInboundRtp.deltaBytesReceived;
275
+ switch (inboundRtp.kind) {
276
+ case 'audio':
277
+ this.deltaReceivedAudioBytes += observedInboundRtp.deltaBytesReceived;
278
+ this.deltaReceivedAudioPackets += observedInboundRtp.deltaReceivedPackets;
279
+ break;
280
+ case 'video':
281
+ this.deltaReceivedVideoBytes += observedInboundRtp.deltaBytesReceived;
282
+ this.deltaReceivedVideoPackets += observedInboundRtp.deltaReceivedPackets;
283
+ break;
284
+ }
285
+ if (observedInboundRtp.jitter) {
286
+ jitterMeasurements.push(observedInboundRtp.jitter);
287
+ }
288
+ }
289
+ }
290
+ if (sample.mediaPlayouts) {
291
+ for (const mediaPlayout of sample.mediaPlayouts) {
292
+ this._updateMediaPlayoutStats(mediaPlayout);
293
+ }
294
+ }
295
+ if (sample.mediaSources) {
296
+ for (const mediaSource of sample.mediaSources) {
297
+ this._updateMediaSourceStats(mediaSource);
298
+ }
299
+ }
300
+ if (sample.outboundRtps) {
301
+ for (const outboundRtp of sample.outboundRtps) {
302
+ const observedOutboundRtp = this._updateOutboundRtpStats(outboundRtp);
303
+ if (!observedOutboundRtp)
304
+ continue;
305
+ this.deltaOutboundPacketsSent += observedOutboundRtp.deltaPacketsSent ?? 0;
306
+ this.deltaOutboundSentBytes += observedOutboundRtp.deltaBytesSent ?? 0;
307
+ switch (outboundRtp.kind) {
308
+ case 'audio':
309
+ this.deltaSentAudioBytes += observedOutboundRtp.deltaBytesSent;
310
+ this.deltaSentAudioBytes += observedOutboundRtp.deltaPacketsSent;
311
+ break;
312
+ case 'video':
313
+ this.deltaSentVideoBytes += observedOutboundRtp.deltaBytesSent;
314
+ this.deltaSentVideoBytes += observedOutboundRtp.deltaPacketsSent;
315
+ break;
316
+ }
317
+ }
318
+ }
319
+ if (sample.peerConnectionTransports) {
320
+ for (const peerConnectionTransport of sample.peerConnectionTransports) {
321
+ const observedTransport = this._updatePeerConnectionTransportStats(peerConnectionTransport);
322
+ if (!observedTransport)
323
+ continue;
324
+ }
325
+ }
326
+ if (sample.remoteInboundRtps) {
327
+ for (const remoteInboundRtp of sample.remoteInboundRtps) {
328
+ const observedRemoteInboundRtp = this._updateRemoteInboundRtpStats(remoteInboundRtp);
329
+ if (!observedRemoteInboundRtp)
330
+ continue;
331
+ if (observedRemoteInboundRtp.roundTripTime) {
332
+ rttMeasurementsInSec.push(observedRemoteInboundRtp.roundTripTime);
333
+ }
334
+ }
335
+ }
336
+ if (sample.remoteOutboundRtps) {
337
+ for (const remoteOutboundRtp of sample.remoteOutboundRtps) {
338
+ const observedRemoteOutboundRtp = this._updateRemoteOutboundRtpStats(remoteOutboundRtp);
339
+ if (!observedRemoteOutboundRtp)
340
+ continue;
341
+ }
342
+ }
343
+ // tracks should be updated last as they are derived stats
344
+ // and depends on base stats but they all received in the sample sample
345
+ if (sample.inboundTracks) {
346
+ for (const inboundTrack of sample.inboundTracks) {
347
+ this._updateInboundTrackSample(inboundTrack);
348
+ }
349
+ }
350
+ if (sample.outboundTracks) {
351
+ for (const outboundTrack of sample.outboundTracks) {
352
+ this._updateOutboundTrackSample(outboundTrack);
353
+ }
354
+ }
333
355
  this.totalInboundPacketsLost += this.deltaInboundPacketsLost;
334
356
  this.totalInboundPacketsReceived += this.deltaInboundPacketsReceived;
335
357
  this.totalOutboundPacketsSent += this.deltaOutboundPacketsSent;
336
- this.totalSentAudioBytes += this.deltaSentAudioBytes;
337
- this.totalSentVideoBytes += this.deltaSentVideoBytes;
358
+ this.totalDataChannelBytesSent += this.deltaDataChannelBytesSent;
359
+ this.totalDataChannelBytesReceived += this.deltaDataChannelBytesReceived;
360
+ this.totalDataChannelMessagesSent += this.deltaDataChannelMessagesSent;
361
+ this.totalDataChannelMessagesReceived += this.deltaDataChannelMessagesReceived;
338
362
  this.totalReceivedAudioBytes += this.deltaReceivedAudioBytes;
339
363
  this.totalReceivedVideoBytes += this.deltaReceivedVideoBytes;
364
+ this.totalSentAudioBytes += this.deltaSentAudioBytes;
365
+ this.totalSentVideoBytes += this.deltaSentVideoBytes;
340
366
  this.totalReceivedAudioPacktes += this.deltaReceivedAudioPackets;
341
367
  this.totalReceivedVideoPackets += this.deltaReceivedVideoPackets;
342
368
  this.totalSentAudioPackets += this.deltaSentAudioBytes;
343
369
  this.totalSentVideoPackets += this.deltaSentVideoBytes;
344
- if (this._elapsedTimeSinceLastUpdate && 0 < this._elapsedTimeSinceLastUpdate) {
345
- this.sendingPacketsPerSecond = this.deltaOutboundPacketsSent / (this._elapsedTimeSinceLastUpdate / 1000);
346
- this.receivingPacketsPerSecond = this.deltaInboundPacketsReceived / (this._elapsedTimeSinceLastUpdate / 1000);
370
+ this.receivingPacketsPerSecond = this.deltaInboundPacketsReceived / elapsedTimeInSec;
371
+ this.sendingPacketsPerSecond = this.deltaOutboundPacketsSent / elapsedTimeInSec;
372
+ this.sendingAudioBitrate = (this.deltaSentAudioBytes * 8) / elapsedTimeInSec;
373
+ this.sendingVideoBitrate = (this.deltaSentVideoBytes * 8) / elapsedTimeInSec;
374
+ this.receivingAudioBitrate = (this.deltaReceivedAudioBytes * 8) / elapsedTimeInSec;
375
+ this.receivingVideoBitrate = (this.deltaReceivedVideoBytes * 8) / elapsedTimeInSec;
376
+ if (rttMeasurementsInSec.length > 0) {
377
+ this.currentRttInMs = (0, utils_1.getMedian)(rttMeasurementsInSec, false) * 1000;
347
378
  }
348
379
  else {
349
- this.sendingPacketsPerSecond = 0;
350
- this.receivingPacketsPerSecond = 0;
351
- }
352
- // calculate quality score
353
- this._updateQualityScore(trackScores);
354
- }
355
- _updateQualityScore(trackScores) {
356
- var _a, _b, _c, _d, _e, _f, _g;
357
- // Packet Jitter measured in seconds
358
- // we use RTT and lost packets to calculate the base score for the connection
359
- const rttInMs = (_a = this.avgRttInMs) !== null && _a !== void 0 ? _a : 0;
360
- const latencyFactor = rttInMs < 150 ? 1.0 : (0, CalculatedScore_1.getRttScore)(rttInMs);
361
- const totalPackets = Math.max(1, ((_b = this.totalInboundPacketsReceived) !== null && _b !== void 0 ? _b : 0) + ((_c = this.totalOutboundPacketsSent) !== null && _c !== void 0 ? _c : 0));
362
- const lostPackets = ((_d = this.totalInboundPacketsLost) !== null && _d !== void 0 ? _d : 0) + ((_e = this.deltaOutboundPacketsSent) !== null && _e !== void 0 ? _e : 0);
363
- const deliveryFactor = 1.0 - ((lostPackets) / (lostPackets + totalPackets));
364
- // let's push the actual stability score
365
- const stabilityScore = Math.pow(((latencyFactor * 0.5) + (deliveryFactor * 0.5)), 2);
366
- this._stabilityScores.push(stabilityScore);
367
- if (10 < this._stabilityScores.length) {
368
- this._stabilityScores.shift();
369
- }
370
- else if (this._stabilityScores.length < 5) {
371
- return;
380
+ this.currentRttInMs = undefined;
381
+ }
382
+ if (jitterMeasurements.length > 0) {
383
+ this.currentJitter = (0, utils_1.getMedian)(jitterMeasurements, false);
384
+ }
385
+ else {
386
+ this.currentJitter = undefined;
387
+ }
388
+ const wasUsingTURN = this.usingTURN;
389
+ const selectedIceCandidatePairs = this.selectedIceCandidatePairs;
390
+ const selectedCandidatePairForTurn = [];
391
+ this.usingTCP = false;
392
+ this.usingTURN = false;
393
+ for (const selectedCandidatePair of selectedIceCandidatePairs) {
394
+ if (selectedCandidatePair.getLocalCandidate()?.protocol === 'tcp') {
395
+ this.usingTCP = true;
396
+ }
397
+ if (selectedCandidatePair.getLocalCandidate()?.candidateType === 'relay' && selectedCandidatePair.getRemoteCandidate()?.url?.startsWith('turn:')) {
398
+ selectedCandidatePairForTurn.push(selectedCandidatePair);
399
+ this.usingTURN = true;
400
+ }
401
+ this.deltaTransportReceivedBytes += selectedCandidatePair.deltaBytesReceived;
402
+ this.deltaTransportSentBytes += selectedCandidatePair.deltaBytesSent;
403
+ }
404
+ if (this.usingTURN) {
405
+ if (!this.observedTurnServer) {
406
+ this.observedTurnServer = this.client.call.observer.observedTURN.addPeerConnection(this);
407
+ }
408
+ this.observedTurnServer?.updateTurnUsage(...selectedCandidatePairForTurn);
409
+ }
410
+ else if (wasUsingTURN) {
411
+ if (!this.usingTURN) {
412
+ this.client.call.observer.observedTURN.removePeerConnection(this);
413
+ }
414
+ }
415
+ this.calculatedScore.value = sample.score;
416
+ this.updated = now;
417
+ this._checkVisited();
418
+ this.emit('update');
419
+ }
420
+ _checkVisited() {
421
+ for (const certificate of [...this.observedCertificates.values()]) {
422
+ if (certificate.visited)
423
+ continue;
424
+ this.observedCertificates.delete(certificate.id);
425
+ }
426
+ for (const codec of [...this.observedCodecs.values()]) {
427
+ if (codec.visited)
428
+ continue;
429
+ this.observedCodecs.delete(codec.id);
430
+ this.emit('removed-codec', codec);
431
+ }
432
+ for (const dataChannel of [...this.observedDataChannels.values()]) {
433
+ if (dataChannel.visited)
434
+ continue;
435
+ this.observedDataChannels.delete(dataChannel.id);
436
+ this.emit('removed-data-channel', dataChannel);
437
+ }
438
+ for (const iceCandidate of [...this.observedIceCandidates.values()]) {
439
+ if (iceCandidate.visited)
440
+ continue;
441
+ this.observedIceCandidates.delete(iceCandidate.id);
442
+ this.emit('removed-ice-candidate', iceCandidate);
443
+ }
444
+ for (const iceCandidatePair of [...this.observedIceCandidatesPair.values()]) {
445
+ if (iceCandidatePair.visited)
446
+ continue;
447
+ this.observedIceCandidatesPair.delete(iceCandidatePair.id);
448
+ this.emit('removed-ice-candidate-pair', iceCandidatePair);
449
+ }
450
+ for (const iceTransport of [...this.observedIceTransports.values()]) {
451
+ if (iceTransport.visited)
452
+ continue;
453
+ this.observedIceTransports.delete(iceTransport.id);
454
+ this.emit('removed-ice-transport', iceTransport);
455
+ }
456
+ for (const inboundRtp of [...this.observedInboundRtps.values()]) {
457
+ if (inboundRtp.visited)
458
+ continue;
459
+ this.observedInboundRtps.delete(inboundRtp.ssrc);
460
+ this.emit('removed-inbound-rtp', inboundRtp);
461
+ }
462
+ for (const inboundTrack of [...this.observedInboundTracks.values()]) {
463
+ if (inboundTrack.visited)
464
+ continue;
465
+ this.observedInboundTracks.delete(inboundTrack.id);
466
+ this.emit('removed-inbound-track', inboundTrack);
467
+ }
468
+ for (const mediaPlayout of [...this.observedMediaPlayouts.values()]) {
469
+ if (mediaPlayout.visited)
470
+ continue;
471
+ this.observedMediaPlayouts.delete(mediaPlayout.id);
472
+ this.emit('removed-media-playout', mediaPlayout);
473
+ }
474
+ for (const mediaSource of [...this.observedMediaSources.values()]) {
475
+ if (mediaSource.visited)
476
+ continue;
477
+ this.observedMediaSources.delete(mediaSource.id);
478
+ this.emit('removed-media-source', mediaSource);
479
+ }
480
+ for (const outboundRtp of [...this.observedOutboundRtps.values()]) {
481
+ if (outboundRtp.visited)
482
+ continue;
483
+ this.observedOutboundRtps.delete(outboundRtp.ssrc);
484
+ this.emit('removed-outbound-rtp', outboundRtp);
485
+ }
486
+ for (const outboundTrack of [...this.observedOutboundTracks.values()]) {
487
+ if (outboundTrack.visited)
488
+ continue;
489
+ this.observedOutboundTracks.delete(outboundTrack.id);
490
+ this.emit('removed-outbound-track', outboundTrack);
491
+ }
492
+ for (const peerConnectionTransport of [...this.observedPeerConnectionTransports.values()]) {
493
+ if (peerConnectionTransport.visited)
494
+ continue;
495
+ this.observedPeerConnectionTransports.delete(peerConnectionTransport.id);
496
+ this.emit('removed-peer-connection-transport', peerConnectionTransport);
497
+ }
498
+ for (const remoteInboundRtp of [...this.observedRemoteInboundRtps.values()]) {
499
+ if (remoteInboundRtp.visited)
500
+ continue;
501
+ this.observedRemoteInboundRtps.delete(remoteInboundRtp.ssrc);
502
+ this.emit('removed-remote-inbound-rtp', remoteInboundRtp);
503
+ }
504
+ for (const remoteOutboundRtp of [...this.observedRemoteOutboundRtps.values()]) {
505
+ if (remoteOutboundRtp.visited)
506
+ continue;
507
+ this.observedRemoteOutboundRtps.delete(remoteOutboundRtp.ssrc);
508
+ this.emit('removed-remote-outbound-rtp', remoteOutboundRtp);
509
+ }
510
+ }
511
+ _updateCertificateStats(stats) {
512
+ let observedCertificate = this.observedCertificates.get(stats.id);
513
+ if (!observedCertificate) {
514
+ if (!stats.timestamp || !stats.id || !stats.fingerprint) {
515
+ return logger.warn(`ObservedPeerConnection received an invalid CertificateStats (missing timestamp OR id OR fingerprint field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
516
+ }
517
+ observedCertificate = new ObservedCertificate_1.ObservedCertificate(stats.timestamp, stats.id, this);
518
+ observedCertificate.update(stats);
519
+ this.observedCertificates.set(stats.id, observedCertificate);
520
+ this.emit('added-certificate', observedCertificate);
521
+ }
522
+ else {
523
+ observedCertificate.update(stats);
524
+ this.emit('updated-certificate', observedCertificate);
525
+ }
526
+ return observedCertificate;
527
+ }
528
+ _updateCodecStats(stats) {
529
+ let observedCodec = this.observedCodecs.get(stats.id);
530
+ if (!observedCodec) {
531
+ if (!stats.timestamp || !stats.id || !stats.mimeType) {
532
+ return logger.warn(`ObservedPeerConnection received an invalid CodecStats (missing timestamp OR id OR mimeType field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
533
+ }
534
+ observedCodec = new ObservedCodec_1.ObservedCodec(stats.timestamp, stats.id, stats.mimeType, this);
535
+ observedCodec.update(stats);
536
+ this.observedCodecs.set(stats.id, observedCodec);
537
+ this.emit('added-codec', observedCodec);
538
+ }
539
+ else {
540
+ observedCodec.update(stats);
541
+ }
542
+ this.emit('updated-codec', observedCodec);
543
+ return observedCodec;
544
+ }
545
+ _updateDataChannelStats(stats) {
546
+ let observedDataChannel = this.observedDataChannels.get(stats.id);
547
+ if (!observedDataChannel) {
548
+ if (!stats.timestamp || !stats.id) {
549
+ return logger.warn(`ObservedPeerConnection received an invalid DataChannelStats (missing timestamp OR id field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
550
+ }
551
+ observedDataChannel = new ObservedDataChannel_1.ObservedDataChannel(stats.timestamp, stats.id, this);
552
+ observedDataChannel.update(stats);
553
+ this.observedDataChannels.set(stats.id, observedDataChannel);
554
+ this.emit('added-data-channel', observedDataChannel);
555
+ }
556
+ else {
557
+ observedDataChannel.update(stats);
558
+ }
559
+ this.emit('updated-data-channel', observedDataChannel);
560
+ return observedDataChannel;
561
+ }
562
+ _updateIceCandidateStats(stats) {
563
+ let observedIceCandidate = this.observedIceCandidates.get(stats.id);
564
+ if (!observedIceCandidate) {
565
+ if (!stats.timestamp || !stats.id) {
566
+ return logger.warn(`ObservedPeerConnection received an invalid IceCandidateStats (missing timestamp OR id field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
567
+ }
568
+ observedIceCandidate = new ObservedIceCandidate_1.ObservedIceCandidate(stats.timestamp, stats.id, this);
569
+ observedIceCandidate.update(stats);
570
+ this.observedIceCandidates.set(stats.id, observedIceCandidate);
571
+ this.emit('added-ice-candidate', observedIceCandidate);
572
+ }
573
+ else {
574
+ observedIceCandidate.update(stats);
575
+ }
576
+ this.emit('updated-ice-candidate', observedIceCandidate);
577
+ return observedIceCandidate;
578
+ }
579
+ _updateIceCandidatePairStats(stats) {
580
+ let observedIceCandidatePair = this.observedIceCandidatesPair.get(stats.id);
581
+ if (!observedIceCandidatePair) {
582
+ if (!stats.timestamp || !stats.id) {
583
+ return logger.warn(`ObservedPeerConnection received an invalid IceCandidateStats (missing timestamp OR id field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
584
+ }
585
+ observedIceCandidatePair = new ObservedIceCandidatePair_1.ObservedIceCandidatePair(stats.timestamp, stats.id, this);
586
+ observedIceCandidatePair.update(stats);
587
+ this.observedIceCandidatesPair.set(stats.id, observedIceCandidatePair);
588
+ this.emit('added-ice-candidate-pair', observedIceCandidatePair);
589
+ }
590
+ else {
591
+ observedIceCandidatePair.update(stats);
592
+ }
593
+ this.emit('updated-ice-candidate-pair', observedIceCandidatePair);
594
+ return observedIceCandidatePair;
595
+ }
596
+ _updateIceTransportStats(stats) {
597
+ let observedIceTransport = this.observedIceTransports.get(stats.id);
598
+ if (!observedIceTransport) {
599
+ if (!stats.timestamp || !stats.id) {
600
+ return logger.warn(`ObservedPeerConnection received an invalid IceCandidateStats (missing timestamp OR id field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
601
+ }
602
+ observedIceTransport = new ObservedIceTransport_1.ObservedIceTransport(stats.timestamp, stats.id, this);
603
+ observedIceTransport.update(stats);
604
+ this.observedIceTransports.set(stats.id, observedIceTransport);
605
+ this.emit('added-ice-transport', observedIceTransport);
606
+ }
607
+ else {
608
+ observedIceTransport.update(stats);
609
+ }
610
+ this.emit('updated-ice-transport', observedIceTransport);
611
+ return observedIceTransport;
612
+ }
613
+ _updateInboundRtpStats(stats) {
614
+ let observedInboundRtp = this.observedInboundRtps.get(stats.ssrc);
615
+ if (!observedInboundRtp) {
616
+ if (!stats.timestamp || !stats.id || !stats.ssrc || !stats.kind || !stats.trackIdentifier) {
617
+ return logger.warn(`ObservedPeerConnection received an invalid InboundRtpStats (missing timestamp OR id OR ssrc OR kind OR trackIdentifier field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
618
+ }
619
+ observedInboundRtp = new ObservedInboundRtp_1.ObservedInboundRtp(stats.timestamp, stats.id, stats.ssrc, stats.kind, stats.trackIdentifier, this);
620
+ observedInboundRtp.update(stats);
621
+ this.observedInboundRtps.set(stats.ssrc, observedInboundRtp);
622
+ this.emit('added-inbound-rtp', observedInboundRtp);
623
+ }
624
+ else {
625
+ observedInboundRtp.update(stats);
626
+ }
627
+ this.emit('updated-inbound-rtp', observedInboundRtp);
628
+ return observedInboundRtp;
629
+ }
630
+ _updateInboundTrackSample(stats) {
631
+ let observedInboundTrack = this.observedInboundTracks.get(stats.id);
632
+ if (!observedInboundTrack) {
633
+ if (!stats.timestamp || !stats.id || !stats.kind) {
634
+ return logger.warn(`ObservedPeerConnection received an invalid InboundTrackSample (missing timestamp OR id OR kind field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
635
+ }
636
+ const inboundRtp = [...this.observedInboundRtps.values()].find((inbRtp) => inbRtp.trackIdentifier === stats.id);
637
+ const mediaPlayout = inboundRtp ?
638
+ [...this.observedMediaPlayouts.values()].find((mp) => mp.id === inboundRtp.playoutId) : undefined;
639
+ observedInboundTrack = new ObservedInboundTrack_1.ObservedInboundTrack(stats.timestamp, stats.id, stats.kind, this, inboundRtp, mediaPlayout);
640
+ observedInboundTrack.update(stats);
641
+ this.observedInboundTracks.set(stats.id, observedInboundTrack);
642
+ this.emit('added-inbound-track', observedInboundTrack);
643
+ }
644
+ else {
645
+ observedInboundTrack.update(stats);
646
+ }
647
+ this.emit('updated-inbound-track', observedInboundTrack);
648
+ return observedInboundTrack;
649
+ }
650
+ _updateMediaPlayoutStats(stats) {
651
+ let observedMediaPlayout = this.observedMediaPlayouts.get(stats.id);
652
+ if (!observedMediaPlayout) {
653
+ if (!stats.timestamp || !stats.id || !stats.kind) {
654
+ return logger.warn(`ObservedPeerConnection received an invalid InboundRtpStats (missing timestamp OR id OR kind OR trackIdentifier field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
655
+ }
656
+ observedMediaPlayout = new ObservedMediaPlayout_1.ObservedMediaPlayout(stats.timestamp, stats.id, stats.kind, this);
657
+ observedMediaPlayout.update(stats);
658
+ this.observedMediaPlayouts.set(stats.id, observedMediaPlayout);
659
+ this.emit('added-media-playout', observedMediaPlayout);
660
+ }
661
+ else {
662
+ observedMediaPlayout.update(stats);
663
+ }
664
+ this.emit('updated-media-playout', observedMediaPlayout);
665
+ return observedMediaPlayout;
666
+ }
667
+ _updateMediaSourceStats(stats) {
668
+ let observedMediaSource = this.observedMediaSources.get(stats.id);
669
+ if (!observedMediaSource) {
670
+ if (!stats.timestamp || !stats.id || !stats.kind) {
671
+ return logger.warn(`ObservedPeerConnection received an invalid InboundRtpStats (missing timestamp OR id OR kind field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
672
+ }
673
+ observedMediaSource = new ObservedMediaSource_1.ObservedMediaSource(stats.timestamp, stats.id, stats.kind, this);
674
+ observedMediaSource.update(stats);
675
+ this.observedMediaSources.set(stats.id, observedMediaSource);
676
+ this.emit('added-media-source', observedMediaSource);
677
+ }
678
+ else {
679
+ observedMediaSource.update(stats);
680
+ }
681
+ this.emit('updated-media-source', observedMediaSource);
682
+ return observedMediaSource;
683
+ }
684
+ _updateOutboundRtpStats(stats) {
685
+ let observedOutboundRtp = this.observedOutboundRtps.get(stats.ssrc);
686
+ if (!observedOutboundRtp) {
687
+ if (!stats.timestamp || !stats.id || !stats.ssrc || !stats.kind) {
688
+ return logger.warn(`ObservedPeerConnection received an invalid OutboundRtpStats (missing timestamp OR id OR ssrc OR kind field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
689
+ }
690
+ observedOutboundRtp = new ObservedOutboundRtp_1.ObservedOutboundRtp(stats.timestamp, stats.id, stats.ssrc, stats.kind, this);
691
+ observedOutboundRtp.update(stats);
692
+ this.observedOutboundRtps.set(stats.ssrc, observedOutboundRtp);
693
+ this.emit('added-outbound-rtp', observedOutboundRtp);
694
+ }
695
+ else {
696
+ observedOutboundRtp.update(stats);
697
+ }
698
+ this.emit('updated-outbound-rtp', observedOutboundRtp);
699
+ return observedOutboundRtp;
700
+ }
701
+ _updateOutboundTrackSample(stats) {
702
+ let observedOutboundTrack = this.observedOutboundTracks.get(stats.id);
703
+ if (!observedOutboundTrack) {
704
+ if (!stats.timestamp || !stats.id || !stats.kind) {
705
+ return logger.warn(`ObservedPeerConnection received an invalid OutboundTrackSample (missing timestamp OR id OR kind field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
706
+ }
707
+ const observedMediaSource = [...this.observedMediaSources.values()].find((mediaSource) => mediaSource.trackIdentifier === stats.id);
708
+ const outboundRtps = observedMediaSource
709
+ ? [...this.observedOutboundRtps.values()].filter((outboundRtp) => outboundRtp.mediaSourceId === observedMediaSource?.id) : undefined;
710
+ observedOutboundTrack = new ObservedOutboundTrack_1.ObservedOutboundTrack(stats.timestamp, stats.id, stats.kind, this, outboundRtps, observedMediaSource);
711
+ observedOutboundTrack.update(stats);
712
+ this.observedOutboundTracks.set(stats.id, observedOutboundTrack);
713
+ this.emit('added-outbound-track', observedOutboundTrack);
714
+ }
715
+ else {
716
+ observedOutboundTrack.update(stats);
717
+ }
718
+ this.emit('updated-outbound-track', observedOutboundTrack);
719
+ return observedOutboundTrack;
720
+ }
721
+ _updatePeerConnectionTransportStats(stats) {
722
+ let observedPeerConnectionTransport = this.observedPeerConnectionTransports.get(stats.id);
723
+ if (!observedPeerConnectionTransport) {
724
+ if (!stats.timestamp || !stats.id) {
725
+ return logger.warn(`ObservedPeerConnection received an invalid PeerConnectionTransportStats (missing timestamp OR id field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
726
+ }
727
+ observedPeerConnectionTransport = new ObservedPeerConnectionTransport_1.ObservedPeerConnectionTransport(stats.timestamp, stats.id, this);
728
+ observedPeerConnectionTransport.update(stats);
729
+ this.observedPeerConnectionTransports.set(stats.id, observedPeerConnectionTransport);
730
+ this.emit('added-peer-connection-transport', observedPeerConnectionTransport);
731
+ }
732
+ else {
733
+ observedPeerConnectionTransport.update(stats);
734
+ }
735
+ this.emit('updated-peer-connection-transport', observedPeerConnectionTransport);
736
+ return observedPeerConnectionTransport;
737
+ }
738
+ _updateRemoteInboundRtpStats(stats) {
739
+ let observedRemoteInboundRtp = this.observedRemoteInboundRtps.get(stats.ssrc);
740
+ if (!observedRemoteInboundRtp) {
741
+ if (!stats.timestamp || !stats.id || !stats.ssrc || !stats.kind) {
742
+ return logger.warn(`ObservedPeerConnection received an invalid RemoteInboundRtpStats (missing timestamp OR id OR ssrc OR kind field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
743
+ }
744
+ observedRemoteInboundRtp = new ObservedRemoteInboundRtp_1.ObservedRemoteInboundRtp(stats.timestamp, stats.id, stats.ssrc, stats.kind, this);
745
+ observedRemoteInboundRtp.update(stats);
746
+ this.observedRemoteInboundRtps.set(stats.ssrc, observedRemoteInboundRtp);
747
+ this.emit('added-remote-inbound-rtp', observedRemoteInboundRtp);
748
+ }
749
+ else {
750
+ observedRemoteInboundRtp.update(stats);
751
+ }
752
+ this.emit('updated-remote-inbound-rtp', observedRemoteInboundRtp);
753
+ return observedRemoteInboundRtp;
754
+ }
755
+ _updateRemoteOutboundRtpStats(stats) {
756
+ let observedRemoteOutboundRtp = this.observedRemoteOutboundRtps.get(stats.ssrc);
757
+ if (!observedRemoteOutboundRtp) {
758
+ if (!stats.timestamp || !stats.id || !stats.ssrc || !stats.kind) {
759
+ return logger.warn(`ObservedPeerConnection received an invalid RemoteOutboundRtpStats (missing timestamp OR id OR ssrc OR kind field). PeerConnectionId: ${this.peerConnectionId} ClientId: ${this.client.clientId}, CallId: ${this.client.call.callId}`, stats);
760
+ }
761
+ observedRemoteOutboundRtp = new ObservedRemoteOutboundRtp_1.ObservedRemoteOutboundRtp(stats.timestamp, stats.id, stats.ssrc, stats.kind, this);
762
+ observedRemoteOutboundRtp.update(stats);
763
+ this.observedRemoteOutboundRtps.set(stats.ssrc, observedRemoteOutboundRtp);
764
+ this.emit('added-remote-outbound-rtp', observedRemoteOutboundRtp);
765
+ }
766
+ else {
767
+ observedRemoteOutboundRtp.update(stats);
372
768
  }
373
- let counter = 0;
374
- let weight = 0;
375
- let totalScore = 0;
376
- for (const score of this._stabilityScores) {
377
- weight += 1;
378
- counter += weight;
379
- totalScore += weight * score;
380
- }
381
- const weightedStabilityScore = totalScore / counter;
382
- let sumTrackScores = 0;
383
- for (const trackScore of trackScores) {
384
- sumTrackScores += trackScore.score;
385
- }
386
- const avgTrackScores = sumTrackScores / trackScores.length;
387
- const score = {
388
- remarks: [{
389
- severity: 'none',
390
- text: `Peer Connection stability score: ${weightedStabilityScore}`,
391
- },
392
- {
393
- severity: 'none',
394
- text: `Avg. Track score: ${avgTrackScores}`,
395
- }],
396
- score: Math.floor((weightedStabilityScore + avgTrackScores) * 5),
397
- timestamp: (_f = this._statsTimestamp) !== null && _f !== void 0 ? _f : Date.now(),
398
- };
399
- for (const pendingIssue of this.ωpendingIssuesForScores) {
400
- switch (pendingIssue.severity) {
401
- case 'critical':
402
- score.score = 0.0;
403
- break;
404
- case 'major':
405
- score.score *= 0.5;
406
- break;
407
- case 'minor':
408
- score.score *= 0.8;
409
- break;
410
- }
411
- score.remarks.push({
412
- severity: pendingIssue.severity,
413
- text: (_g = pendingIssue.description) !== null && _g !== void 0 ? _g : 'Issue occurred',
414
- });
415
- }
416
- this.ωpendingIssuesForScores = [];
417
- this.score = score;
418
- this.emit('score', score);
769
+ this.emit('updated-remote-outbound-rtp', observedRemoteOutboundRtp);
770
+ return observedRemoteOutboundRtp;
419
771
  }
420
772
  }
421
773
  exports.ObservedPeerConnection = ObservedPeerConnection;