@webex/plugin-meetings 2.59.8 → 2.60.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -8
- package/dist/annotation/annotation.types.d.ts +42 -0
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.d.ts +31 -0
- package/dist/annotation/constants.js +41 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.d.ts +117 -0
- package/dist/annotation/index.js +357 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.d.ts +8 -0
- package/dist/breakouts/breakout.js +215 -0
- package/dist/breakouts/breakout.js.map +1 -0
- package/dist/breakouts/collection.d.ts +5 -0
- package/dist/breakouts/collection.js +22 -0
- package/dist/breakouts/collection.js.map +1 -0
- package/dist/breakouts/edit-lock-error.d.ts +15 -0
- package/dist/breakouts/edit-lock-error.js +51 -0
- package/dist/breakouts/edit-lock-error.js.map +1 -0
- package/dist/breakouts/events.d.ts +8 -0
- package/dist/breakouts/events.js +44 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.d.ts +5 -0
- package/dist/breakouts/index.js +1047 -0
- package/dist/breakouts/index.js.map +1 -0
- package/dist/breakouts/request.d.ts +22 -0
- package/dist/breakouts/request.js +77 -0
- package/dist/breakouts/request.js.map +1 -0
- package/dist/breakouts/utils.d.ts +15 -0
- package/dist/breakouts/utils.js +64 -0
- package/dist/breakouts/utils.js.map +1 -0
- package/dist/common/browser-detection.js +2 -3
- package/dist/common/browser-detection.js.map +1 -1
- package/dist/common/collection.js +3 -4
- package/dist/common/collection.js.map +1 -1
- package/dist/common/config.js +1 -2
- package/dist/common/config.js.map +1 -1
- package/dist/common/errors/captcha-error.js +1 -2
- package/dist/common/errors/captcha-error.js.map +1 -1
- package/dist/common/errors/intent-to-join.js +1 -2
- package/dist/common/errors/intent-to-join.js.map +1 -1
- package/dist/common/errors/join-meeting.js +1 -2
- package/dist/common/errors/join-meeting.js.map +1 -1
- package/dist/common/errors/media.js +1 -2
- package/dist/common/errors/media.js.map +1 -1
- package/dist/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/common/errors/no-meeting-info.js +50 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/parameter.js +3 -4
- package/dist/common/errors/parameter.js.map +1 -1
- package/dist/common/errors/password-error.js +1 -2
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +1 -2
- package/dist/common/errors/permission.js.map +1 -1
- package/dist/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/common/errors/reclaim-host-role-errors.js +154 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/reconnection-in-progress.js +1 -2
- package/dist/common/errors/reconnection-in-progress.js.map +1 -1
- package/dist/common/errors/reconnection.js +1 -2
- package/dist/common/errors/reconnection.js.map +1 -1
- package/dist/common/errors/stats.js +1 -2
- package/dist/common/errors/stats.js.map +1 -1
- package/dist/common/errors/webex-errors.d.ts +20 -8
- package/dist/common/errors/webex-errors.js +48 -28
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/errors/webex-meetings-error.js +1 -2
- package/dist/common/errors/webex-meetings-error.js.map +1 -1
- package/dist/common/events/events-scope.js +1 -2
- package/dist/common/events/events-scope.js.map +1 -1
- package/dist/common/events/events.js +1 -2
- package/dist/common/events/events.js.map +1 -1
- package/dist/common/events/trigger-proxy.js +1 -2
- package/dist/common/events/trigger-proxy.js.map +1 -1
- package/dist/common/events/util.js +1 -2
- package/dist/common/events/util.js.map +1 -1
- package/dist/common/logs/logger-config.js +1 -2
- package/dist/common/logs/logger-config.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +2 -3
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.d.ts +3 -1
- package/dist/common/logs/request.js +8 -5
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.d.ts +9 -7
- package/dist/common/queue.js +22 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.d.ts +5 -7
- package/dist/config.js +8 -11
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +243 -97
- package/dist/constants.js +437 -435
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js +3 -6
- package/dist/controls-options-manager/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.d.ts +11 -1
- package/dist/controls-options-manager/enums.js +15 -6
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.d.ts +17 -1
- package/dist/controls-options-manager/index.js +127 -38
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.d.ts +43 -0
- package/dist/controls-options-manager/types.js +7 -0
- package/dist/controls-options-manager/types.js.map +1 -0
- package/dist/controls-options-manager/util.d.ts +1 -7
- package/dist/controls-options-manager/util.js +309 -19
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +116 -4
- package/dist/index.js.map +1 -1
- package/dist/interpretation/collection.d.ts +5 -0
- package/dist/interpretation/collection.js +22 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.d.ts +5 -0
- package/dist/interpretation/index.js +365 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.d.ts +5 -0
- package/dist/interpretation/siLanguage.js +24 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +100 -11
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/embeddedAppsUtils.js +3 -4
- package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
- package/dist/locus-info/fullState.js +1 -2
- package/dist/locus-info/fullState.js.map +1 -1
- package/dist/locus-info/hostUtils.js +1 -2
- package/dist/locus-info/hostUtils.js.map +1 -1
- package/dist/locus-info/index.d.ts +57 -4
- package/dist/locus-info/index.js +425 -84
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +13 -5
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +58 -3
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.d.ts +66 -6
- package/dist/locus-info/parser.js +253 -80
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +97 -13
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.d.ts +2 -0
- package/dist/media/index.js +107 -319
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.d.ts +38 -53
- package/dist/media/properties.js +96 -153
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js +1 -22
- package/dist/media/util.js.map +1 -1
- package/dist/mediaQualityMetrics/config.d.ts +234 -230
- package/dist/mediaQualityMetrics/config.js +302 -498
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.d.ts +88 -0
- package/dist/meeting/in-meeting-actions.js +94 -3
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.d.ts +591 -494
- package/dist/meeting/index.js +4728 -2990
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/meeting/locusMediaRequest.js +291 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.d.ts +93 -25
- package/dist/meeting/muteState.js +224 -133
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.d.ts +82 -47
- package/dist/meeting/request.js +297 -199
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.d.ts +11 -0
- package/dist/meeting/request.type.js +7 -0
- package/dist/meeting/request.type.js.map +1 -0
- package/dist/meeting/state.js +1 -2
- package/dist/meeting/state.js.map +1 -1
- package/dist/meeting/util.d.ts +102 -1
- package/dist/meeting/util.js +605 -435
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/collection.js +3 -4
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/meeting-info/index.d.ts +13 -1
- package/dist/meeting-info/index.js +74 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.d.ts +31 -1
- package/dist/meeting-info/meeting-info-v2.js +200 -63
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/request.js +1 -2
- package/dist/meeting-info/request.js.map +1 -1
- package/dist/meeting-info/util.js +2 -3
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +39 -41
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.d.ts +17 -0
- package/dist/meetings/collection.js +42 -4
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.d.ts +103 -21
- package/dist/meetings/index.js +486 -124
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.d.ts +4 -0
- package/dist/meetings/meetings.types.js +7 -0
- package/dist/meetings/meetings.types.js.map +1 -0
- package/dist/meetings/request.js +4 -3
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +107 -6
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.d.ts +14 -1
- package/dist/member/index.js +54 -2
- package/dist/member/index.js.map +1 -1
- package/dist/member/member.types.js +3 -4
- package/dist/member/member.types.js.map +1 -1
- package/dist/member/types.d.ts +32 -0
- package/dist/member/types.js +23 -0
- package/dist/member/types.js.map +1 -0
- package/dist/member/util.js +131 -29
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.d.ts +5 -0
- package/dist/members/collection.js +11 -2
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.d.ts +57 -2
- package/dist/members/index.js +174 -10
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.d.ts +73 -9
- package/dist/members/request.js +108 -41
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.d.ts +25 -0
- package/dist/members/types.js +14 -0
- package/dist/members/types.js.map +1 -0
- package/dist/members/util.d.ts +214 -1
- package/dist/members/util.js +327 -234
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.d.ts +15 -6
- package/dist/metrics/constants.js +17 -9
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.d.ts +4 -111
- package/dist/metrics/index.js +4 -452
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.d.ts +118 -0
- package/dist/multistream/mediaRequestManager.js +344 -0
- package/dist/multistream/mediaRequestManager.js.map +1 -0
- package/dist/multistream/receiveSlot.d.ts +68 -0
- package/dist/multistream/receiveSlot.js +200 -0
- package/dist/multistream/receiveSlot.js.map +1 -0
- package/dist/multistream/receiveSlotManager.d.ts +56 -0
- package/dist/multistream/receiveSlotManager.js +174 -0
- package/dist/multistream/receiveSlotManager.js.map +1 -0
- package/dist/multistream/remoteMedia.d.ts +72 -0
- package/dist/multistream/remoteMedia.js +268 -0
- package/dist/multistream/remoteMedia.js.map +1 -0
- package/dist/multistream/remoteMediaGroup.d.ts +47 -0
- package/dist/multistream/remoteMediaGroup.js +267 -0
- package/dist/multistream/remoteMediaGroup.js.map +1 -0
- package/dist/multistream/remoteMediaManager.d.ts +285 -0
- package/dist/multistream/remoteMediaManager.js +1211 -0
- package/dist/multistream/remoteMediaManager.js.map +1 -0
- package/dist/multistream/sendSlotManager.d.ts +61 -0
- package/dist/multistream/sendSlotManager.js +236 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/networkQualityMonitor/index.js +5 -4
- package/dist/networkQualityMonitor/index.js.map +1 -1
- package/dist/personal-meeting-room/index.js +2 -3
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/personal-meeting-room/request.js +2 -3
- package/dist/personal-meeting-room/request.js.map +1 -1
- package/dist/personal-meeting-room/util.js +1 -2
- package/dist/personal-meeting-room/util.js.map +1 -1
- package/dist/reachability/index.d.ts +62 -7
- package/dist/reachability/index.js +265 -72
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.d.ts +7 -3
- package/dist/reachability/request.js +18 -10
- package/dist/reachability/request.js.map +1 -1
- package/dist/reactions/constants.d.ts +3 -0
- package/dist/reactions/constants.js +12 -0
- package/dist/reactions/constants.js.map +1 -0
- package/dist/reactions/reactions.d.ts +2 -2
- package/dist/reactions/reactions.js +4 -6
- package/dist/reactions/reactions.js.map +1 -1
- package/dist/reactions/reactions.type.d.ts +23 -3
- package/dist/reactions/reactions.type.js +21 -23
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.d.ts +32 -8
- package/dist/reconnection-manager/index.js +282 -231
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/enums.js +4 -5
- package/dist/recording-controller/enums.js.map +1 -1
- package/dist/recording-controller/index.d.ts +15 -1
- package/dist/recording-controller/index.js +57 -46
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.d.ts +5 -4
- package/dist/recording-controller/util.js +10 -10
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.d.ts +9 -47
- package/dist/roap/index.js +101 -235
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.d.ts +18 -12
- package/dist/roap/request.js +126 -180
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.d.ts +27 -16
- package/dist/roap/turnDiscovery.js +115 -105
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.d.ts +4 -0
- package/dist/rtcMetrics/constants.js +11 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.d.ts +54 -0
- package/dist/rtcMetrics/index.js +140 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/global.d.ts +1 -83
- package/dist/statsAnalyzer/global.js +2 -85
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.d.ts +28 -30
- package/dist/statsAnalyzer/index.js +374 -509
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.d.ts +8 -6
- package/dist/statsAnalyzer/mqaUtil.js +116 -83
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/transcription/index.js +1 -2
- package/dist/transcription/index.js.map +1 -1
- package/dist/webinar/collection.d.ts +16 -0
- package/dist/webinar/collection.js +43 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.d.ts +5 -0
- package/dist/webinar/index.js +68 -0
- package/dist/webinar/index.js.map +1 -0
- package/package.json +35 -26
- package/src/annotation/annotation.types.ts +50 -0
- package/src/annotation/constants.ts +36 -0
- package/src/annotation/index.ts +328 -0
- package/src/breakouts/README.md +220 -0
- package/src/breakouts/breakout.ts +188 -0
- package/src/breakouts/collection.ts +19 -0
- package/src/breakouts/edit-lock-error.ts +25 -0
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +925 -0
- package/src/breakouts/request.ts +55 -0
- package/src/breakouts/utils.ts +57 -0
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/reclaim-host-role-errors.ts +134 -0
- package/src/common/errors/webex-errors.ts +36 -12
- package/src/common/logs/logger-proxy.ts +1 -1
- package/src/common/logs/request.ts +5 -1
- package/src/common/queue.ts +22 -8
- package/src/config.ts +5 -7
- package/src/constants.ts +271 -93
- package/src/controls-options-manager/enums.ts +12 -0
- package/src/controls-options-manager/index.ts +116 -21
- package/src/controls-options-manager/types.ts +59 -0
- package/src/controls-options-manager/util.ts +294 -14
- package/src/index.ts +40 -0
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +332 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +110 -0
- package/src/locus-info/index.ts +449 -61
- package/src/locus-info/infoUtils.ts +14 -2
- package/src/locus-info/mediaSharesUtils.ts +64 -0
- package/src/locus-info/parser.ts +258 -47
- package/src/locus-info/selfUtils.ts +85 -2
- package/src/media/index.ts +153 -370
- package/src/media/properties.ts +106 -136
- package/src/media/util.ts +0 -21
- package/src/mediaQualityMetrics/config.ts +244 -377
- package/src/meeting/in-meeting-actions.ts +176 -0
- package/src/meeting/index.ts +3895 -2448
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +224 -138
- package/src/meeting/request.ts +207 -127
- package/src/meeting/request.type.ts +13 -0
- package/src/meeting/util.ts +590 -423
- package/src/meeting-info/index.ts +81 -8
- package/src/meeting-info/meeting-info-v2.ts +163 -13
- package/src/meeting-info/util.ts +1 -1
- package/src/meeting-info/utilv2.ts +28 -28
- package/src/meetings/collection.ts +33 -0
- package/src/meetings/index.ts +486 -126
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +116 -5
- package/src/member/index.ts +52 -1
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +139 -28
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +196 -7
- package/src/members/request.ts +97 -17
- package/src/members/types.ts +29 -0
- package/src/members/util.ts +333 -240
- package/src/metrics/constants.ts +15 -6
- package/src/metrics/index.ts +1 -471
- package/src/multistream/mediaRequestManager.ts +440 -0
- package/src/multistream/receiveSlot.ts +184 -0
- package/src/multistream/receiveSlotManager.ts +166 -0
- package/src/multistream/remoteMedia.ts +254 -0
- package/src/multistream/remoteMediaGroup.ts +284 -0
- package/src/multistream/remoteMediaManager.ts +1145 -0
- package/src/multistream/sendSlotManager.ts +170 -0
- package/src/networkQualityMonitor/index.ts +6 -6
- package/src/reachability/index.ts +238 -45
- package/src/reachability/request.ts +17 -8
- package/src/reactions/constants.ts +4 -0
- package/src/reactions/reactions.ts +4 -4
- package/src/reactions/reactions.type.ts +30 -4
- package/src/reconnection-manager/index.ts +168 -156
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +98 -241
- package/src/roap/request.ts +74 -148
- package/src/roap/turnDiscovery.ts +62 -56
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +124 -0
- package/src/statsAnalyzer/global.ts +1 -84
- package/src/statsAnalyzer/index.ts +413 -642
- package/src/statsAnalyzer/mqaUtil.ts +111 -114
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +233 -0
- package/test/integration/spec/journey.js +320 -264
- package/test/integration/spec/space-meeting.js +77 -4
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +237 -0
- package/test/unit/spec/breakouts/collection.ts +15 -0
- package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
- package/test/unit/spec/breakouts/events.ts +89 -0
- package/test/unit/spec/breakouts/index.ts +1790 -0
- package/test/unit/spec/breakouts/request.ts +104 -0
- package/test/unit/spec/breakouts/utils.js +72 -0
- package/test/unit/spec/common/queue.js +31 -2
- package/test/unit/spec/controls-options-manager/index.js +163 -0
- package/test/unit/spec/controls-options-manager/util.js +576 -60
- package/test/unit/spec/fixture/locus.js +1 -0
- package/test/unit/spec/interpretation/collection.ts +15 -0
- package/test/unit/spec/interpretation/index.ts +589 -0
- package/test/unit/spec/interpretation/siLanguage.ts +28 -0
- package/test/unit/spec/locus-info/controlsUtils.js +323 -30
- package/test/unit/spec/locus-info/index.js +1390 -16
- package/test/unit/spec/locus-info/infoUtils.js +54 -16
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/lib/selfConstant.js +48 -0
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
- package/test/unit/spec/locus-info/parser.js +116 -35
- package/test/unit/spec/locus-info/selfUtils.js +275 -0
- package/test/unit/spec/media/index.ts +290 -0
- package/test/unit/spec/media/properties.ts +75 -84
- package/test/unit/spec/meeting/in-meeting-actions.ts +86 -0
- package/test/unit/spec/meeting/index.js +8181 -2770
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +409 -213
- package/test/unit/spec/meeting/request.js +512 -42
- package/test/unit/spec/meeting/utils.js +741 -24
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +527 -5
- package/test/unit/spec/meeting-info/utilv2.js +21 -0
- package/test/unit/spec/meetings/collection.js +26 -0
- package/test/unit/spec/meetings/index.js +1284 -217
- package/test/unit/spec/meetings/utils.js +202 -2
- package/test/unit/spec/member/index.js +38 -8
- package/test/unit/spec/member/util.js +499 -29
- package/test/unit/spec/members/index.js +597 -3
- package/test/unit/spec/members/request.js +206 -27
- package/test/unit/spec/members/utils.js +210 -0
- package/test/unit/spec/metrics/index.js +1 -50
- package/test/unit/spec/multistream/mediaRequestManager.ts +1418 -0
- package/test/unit/spec/multistream/receiveSlot.ts +163 -0
- package/test/unit/spec/multistream/receiveSlotManager.ts +203 -0
- package/test/unit/spec/multistream/remoteMedia.ts +255 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +662 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +1924 -0
- package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
- package/test/unit/spec/networkQualityMonitor/index.js +4 -4
- package/test/unit/spec/reachability/index.ts +598 -24
- package/test/unit/spec/reachability/request.js +68 -0
- package/test/unit/spec/reconnection-manager/index.js +162 -24
- package/test/unit/spec/recording-controller/index.js +293 -218
- package/test/unit/spec/recording-controller/util.js +223 -96
- package/test/unit/spec/roap/index.ts +200 -76
- package/test/unit/spec/roap/request.ts +232 -0
- package/test/unit/spec/roap/turnDiscovery.ts +86 -48
- package/test/unit/spec/rtcMetrics/index.ts +93 -0
- package/test/unit/spec/stats-analyzer/index.js +188 -174
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- package/test/utils/constants.js +9 -0
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +0 -45
- package/test/utils/webex-config.js +4 -0
- package/test/utils/webex-test-users.js +7 -3
- package/dist/meeting/effectsState.d.ts +0 -42
- package/dist/meeting/effectsState.js +0 -260
- package/dist/meeting/effectsState.js.map +0 -1
- package/dist/metrics/config.d.ts +0 -169
- package/dist/metrics/config.js +0 -289
- package/dist/metrics/config.js.map +0 -1
- package/dist/peer-connection-manager/index.d.ts +0 -6
- package/dist/peer-connection-manager/index.js +0 -671
- package/dist/peer-connection-manager/index.js.map +0 -1
- package/dist/peer-connection-manager/util.d.ts +0 -6
- package/dist/peer-connection-manager/util.js +0 -110
- package/dist/peer-connection-manager/util.js.map +0 -1
- package/dist/roap/collection.d.ts +0 -10
- package/dist/roap/collection.js +0 -63
- package/dist/roap/collection.js.map +0 -1
- package/dist/roap/handler.d.ts +0 -47
- package/dist/roap/handler.js +0 -279
- package/dist/roap/handler.js.map +0 -1
- package/dist/roap/state.d.ts +0 -9
- package/dist/roap/state.js +0 -127
- package/dist/roap/state.js.map +0 -1
- package/dist/roap/util.d.ts +0 -2
- package/dist/roap/util.js +0 -76
- package/dist/roap/util.js.map +0 -1
- package/src/index.js +0 -15
- package/src/meeting/effectsState.ts +0 -209
- package/src/metrics/config.ts +0 -485
- package/src/peer-connection-manager/index.ts +0 -847
- package/src/peer-connection-manager/util.ts +0 -119
- package/src/roap/collection.ts +0 -62
- package/src/roap/handler.ts +0 -294
- package/src/roap/state.ts +0 -156
- package/src/roap/util.ts +0 -100
- package/test/unit/spec/meeting/effectsState.js +0 -281
- package/test/unit/spec/peerconnection-manager/index.js +0 -218
- package/test/unit/spec/peerconnection-manager/utils.js +0 -49
- package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -388
- package/test/unit/spec/roap/util.js +0 -30
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
/* eslint-disable prefer-destructuring */
|
|
2
2
|
|
|
3
3
|
import {cloneDeep} from 'lodash';
|
|
4
|
+
import {ConnectionState} from '@webex/internal-media-core';
|
|
4
5
|
|
|
5
6
|
import EventsScope from '../common/events/events-scope';
|
|
6
7
|
import {
|
|
7
8
|
DEFAULT_GET_STATS_FILTER,
|
|
8
|
-
CONNECTION_STATE,
|
|
9
9
|
STATS,
|
|
10
10
|
MQA_INTEVAL,
|
|
11
11
|
NETWORK_TYPE,
|
|
12
12
|
MEDIA_DEVICES,
|
|
13
13
|
_UNKNOWN_,
|
|
14
14
|
} from '../constants';
|
|
15
|
-
import
|
|
15
|
+
import {
|
|
16
|
+
emptyAudioReceive,
|
|
17
|
+
emptyAudioTransmit,
|
|
18
|
+
emptyMqaInterval,
|
|
19
|
+
emptyVideoReceive,
|
|
20
|
+
emptyVideoTransmit,
|
|
21
|
+
} from '../mediaQualityMetrics/config';
|
|
16
22
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
17
23
|
|
|
18
24
|
import defaultStats from './global';
|
|
@@ -22,17 +28,34 @@ import {
|
|
|
22
28
|
getVideoSenderMqa,
|
|
23
29
|
getVideoReceiverMqa,
|
|
24
30
|
} from './mqaUtil';
|
|
31
|
+
import {ReceiveSlot} from '../multistream/receiveSlot';
|
|
25
32
|
|
|
26
33
|
export const EVENTS = {
|
|
27
34
|
MEDIA_QUALITY: 'MEDIA_QUALITY',
|
|
28
|
-
NO_FRAMES_SENT: 'NO_FRAMES_SENT',
|
|
29
|
-
NO_VIDEO_ENCODED: 'NO_VIDEO_ENCODED',
|
|
30
35
|
LOCAL_MEDIA_STARTED: 'LOCAL_MEDIA_STARTED',
|
|
31
36
|
LOCAL_MEDIA_STOPPED: 'LOCAL_MEDIA_STOPPED',
|
|
32
37
|
REMOTE_MEDIA_STARTED: 'REMOTE_MEDIA_STARTED',
|
|
33
38
|
REMOTE_MEDIA_STOPPED: 'REMOTE_MEDIA_STOPPED',
|
|
34
39
|
};
|
|
35
40
|
|
|
41
|
+
const emptySender = {
|
|
42
|
+
trackLabel: '',
|
|
43
|
+
maxPacketLossRatio: 0,
|
|
44
|
+
availableBandwidth: 0,
|
|
45
|
+
bytesSent: 0,
|
|
46
|
+
meanRemoteJitter: [],
|
|
47
|
+
meanRoundTripTime: [],
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const emptyReceiver = {
|
|
51
|
+
availableBandwidth: 0,
|
|
52
|
+
bytesReceived: 0,
|
|
53
|
+
meanRtpJitter: [],
|
|
54
|
+
meanRoundTripTime: [],
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
type ReceiveSlotCallback = (csi: number) => ReceiveSlot | undefined;
|
|
58
|
+
|
|
36
59
|
/**
|
|
37
60
|
* Stats Analyzer class that will emit events based on detected quality
|
|
38
61
|
*
|
|
@@ -46,26 +69,29 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
46
69
|
lastEmittedStartStopEvent: any;
|
|
47
70
|
lastMqaDataSent: any;
|
|
48
71
|
lastStatsResults: any;
|
|
49
|
-
localMQEStats: any;
|
|
50
72
|
meetingMediaStatus: any;
|
|
51
73
|
mqaInterval: NodeJS.Timeout;
|
|
52
74
|
mqaSentCount: any;
|
|
53
75
|
networkQualityMonitor: any;
|
|
54
|
-
|
|
76
|
+
mediaConnection: any;
|
|
55
77
|
statsInterval: NodeJS.Timeout;
|
|
56
78
|
statsResults: any;
|
|
57
79
|
statsStarted: any;
|
|
80
|
+
successfulCandidatePair: any;
|
|
81
|
+
receiveSlotCallback: ReceiveSlotCallback;
|
|
58
82
|
|
|
59
83
|
/**
|
|
60
84
|
* Creates a new instance of StatsAnalyzer
|
|
61
85
|
* @constructor
|
|
62
86
|
* @public
|
|
63
87
|
* @param {Object} config SDK Configuration Object
|
|
88
|
+
* @param {Function} receiveSlotCallback Callback used to access receive slots.
|
|
64
89
|
* @param {Object} networkQualityMonitor class for assessing network characteristics (jitter, packetLoss, latency)
|
|
65
90
|
* @param {Object} statsResults Default properties for stats
|
|
66
91
|
*/
|
|
67
92
|
constructor(
|
|
68
93
|
config: any,
|
|
94
|
+
receiveSlotCallback: ReceiveSlotCallback = () => undefined,
|
|
69
95
|
networkQualityMonitor: object = {},
|
|
70
96
|
statsResults: object = defaultStats
|
|
71
97
|
) {
|
|
@@ -77,147 +103,30 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
77
103
|
this.networkQualityMonitor = networkQualityMonitor;
|
|
78
104
|
this.correlationId = config.correlationId;
|
|
79
105
|
this.mqaSentCount = -1;
|
|
80
|
-
this.lastMqaDataSent = {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
share: {send: {}, recv: {}},
|
|
85
|
-
},
|
|
86
|
-
video: {send: {}, recv: {}},
|
|
87
|
-
audio: {send: {}, recv: {}},
|
|
88
|
-
share: {send: {}, recv: {}},
|
|
89
|
-
};
|
|
90
|
-
this.localMQEStats = {
|
|
91
|
-
audio: {
|
|
92
|
-
RX: {
|
|
93
|
-
packetsLost: [],
|
|
94
|
-
jitter: [],
|
|
95
|
-
latency: [],
|
|
96
|
-
bitRate: [],
|
|
97
|
-
},
|
|
98
|
-
TX: {
|
|
99
|
-
packetsLost: [],
|
|
100
|
-
jitter: [],
|
|
101
|
-
latency: [],
|
|
102
|
-
bitRate: [],
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
video: {
|
|
106
|
-
RX: {
|
|
107
|
-
packetsLost: [],
|
|
108
|
-
jitter: [],
|
|
109
|
-
latency: [],
|
|
110
|
-
bitRate: [],
|
|
111
|
-
frameRate: [],
|
|
112
|
-
resolutionWidth: [],
|
|
113
|
-
resolutionHeight: [],
|
|
114
|
-
requestedKeyFrame: [],
|
|
115
|
-
receivedKeyFrame: [],
|
|
116
|
-
},
|
|
117
|
-
TX: {
|
|
118
|
-
packetsLost: [],
|
|
119
|
-
jitter: [],
|
|
120
|
-
latency: [],
|
|
121
|
-
bitRate: [],
|
|
122
|
-
frameRate: [],
|
|
123
|
-
resolutionWidth: [],
|
|
124
|
-
resolutionHeight: [],
|
|
125
|
-
requestedKeyFrame: [],
|
|
126
|
-
receivedKeyFrame: [],
|
|
127
|
-
},
|
|
128
|
-
},
|
|
129
|
-
};
|
|
130
|
-
this.lastEmittedStartStopEvent = {
|
|
131
|
-
audio: {
|
|
132
|
-
local: undefined,
|
|
133
|
-
remote: undefined,
|
|
134
|
-
},
|
|
135
|
-
video: {
|
|
136
|
-
local: undefined,
|
|
137
|
-
remote: undefined,
|
|
138
|
-
},
|
|
139
|
-
share: {
|
|
140
|
-
local: undefined,
|
|
141
|
-
remote: undefined,
|
|
142
|
-
},
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
populateResults(lastMqa) {
|
|
147
|
-
// Audio
|
|
148
|
-
|
|
149
|
-
this.localMQEStats.audio.RX.packetsLost.push(lastMqa.audioReceive[0].common.mediaHopByHopLost);
|
|
150
|
-
this.localMQEStats.audio.RX.jitter.push(lastMqa.audioReceive[0].streams[0].common.rtpJitter);
|
|
151
|
-
this.localMQEStats.audio.RX.latency.push(lastMqa.audioReceive[0].common.roundTripTime);
|
|
152
|
-
this.localMQEStats.audio.RX.bitRate.push(
|
|
153
|
-
lastMqa.audioReceive[0].streams[0].common.receivedBitrate
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
this.localMQEStats.audio.TX.packetsLost.push(lastMqa.audioTransmit[0].common.remoteLossRate);
|
|
157
|
-
this.localMQEStats.audio.TX.jitter.push(lastMqa.audioTransmit[0].common.remoteJitter);
|
|
158
|
-
this.localMQEStats.audio.TX.latency.push(lastMqa.audioTransmit[0].common.roundTripTime);
|
|
159
|
-
this.localMQEStats.audio.TX.bitRate.push(
|
|
160
|
-
lastMqa.audioTransmit[0].streams[0].common.transmittedBitrate
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
// Video
|
|
164
|
-
|
|
165
|
-
this.localMQEStats.video.RX.packetsLost.push(lastMqa.videoReceive[0].common.mediaHopByHopLost);
|
|
166
|
-
this.localMQEStats.video.RX.jitter.push(lastMqa.videoReceive[0].streams[0].common.rtpJitter);
|
|
167
|
-
this.localMQEStats.video.RX.latency.push(
|
|
168
|
-
lastMqa.videoReceive[0].streams[0].common.roundTripTime
|
|
169
|
-
);
|
|
170
|
-
this.localMQEStats.video.RX.bitRate.push(
|
|
171
|
-
lastMqa.videoReceive[0].streams[0].common.receivedBitrate
|
|
172
|
-
);
|
|
173
|
-
this.localMQEStats.video.RX.frameRate.push(
|
|
174
|
-
lastMqa.videoReceive[0].streams[0].common.receivedFrameRate
|
|
175
|
-
);
|
|
176
|
-
this.localMQEStats.video.RX.resolutionWidth.push(
|
|
177
|
-
lastMqa.videoReceive[0].streams[0].receivedWidth
|
|
178
|
-
);
|
|
179
|
-
this.localMQEStats.video.RX.resolutionHeight.push(
|
|
180
|
-
lastMqa.videoReceive[0].streams[0].receivedHeight
|
|
181
|
-
);
|
|
182
|
-
this.localMQEStats.video.RX.requestedKeyFrame.push();
|
|
183
|
-
this.localMQEStats.video.RX.receivedKeyFrame.push();
|
|
184
|
-
|
|
185
|
-
this.localMQEStats.video.TX.packetsLost.push(lastMqa.videoTransmit[0].common.remoteLossRate);
|
|
186
|
-
this.localMQEStats.video.TX.jitter.push(lastMqa.videoTransmit[0].common.remoteJitter);
|
|
187
|
-
this.localMQEStats.video.TX.latency.push(lastMqa.videoTransmit[0].common.roundTripTime);
|
|
188
|
-
this.localMQEStats.video.TX.bitRate.push(
|
|
189
|
-
lastMqa.videoTransmit[0].streams[0].common.transmittedBitrate
|
|
190
|
-
);
|
|
191
|
-
this.localMQEStats.video.TX.frameRate.push(
|
|
192
|
-
lastMqa.videoTransmit[0].streams[0].common.transmittedFrameRate
|
|
193
|
-
);
|
|
194
|
-
this.localMQEStats.video.TX.resolutionWidth.push(
|
|
195
|
-
lastMqa.videoTransmit[0].streams[0].transmittedWidth
|
|
196
|
-
);
|
|
197
|
-
this.localMQEStats.video.TX.resolutionHeight.push(
|
|
198
|
-
lastMqa.videoTransmit[0].streams[0].transmittedHeight
|
|
199
|
-
);
|
|
200
|
-
this.localMQEStats.video.TX.requestedKeyFrame.push(
|
|
201
|
-
lastMqa.videoTransmit[0].streams[0].requestedKeyFrames
|
|
202
|
-
);
|
|
203
|
-
this.localMQEStats.video.TX.receivedKeyFrame.push();
|
|
106
|
+
this.lastMqaDataSent = {};
|
|
107
|
+
this.lastEmittedStartStopEvent = {};
|
|
108
|
+
this.receiveSlotCallback = receiveSlotCallback;
|
|
109
|
+
this.successfulCandidatePair = {};
|
|
204
110
|
}
|
|
205
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Resets cumulative stats arrays.
|
|
114
|
+
*
|
|
115
|
+
* @public
|
|
116
|
+
* @memberof StatsAnalyzer
|
|
117
|
+
* @returns {void}
|
|
118
|
+
*/
|
|
206
119
|
resetStatsResults() {
|
|
207
|
-
this.statsResults.
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
this.statsResults.audio.recv.meanRtpJitter = [];
|
|
212
|
-
|
|
213
|
-
// TODO: currently no values are present
|
|
214
|
-
this.statsResults.video.recv.meanRtpJitter = [];
|
|
215
|
-
this.statsResults.share.recv.meanRtpJitter = [];
|
|
120
|
+
Object.keys(this.statsResults).forEach((mediaType) => {
|
|
121
|
+
if (mediaType.includes('recv')) {
|
|
122
|
+
this.statsResults[mediaType].recv.meanRtpJitter = [];
|
|
123
|
+
}
|
|
216
124
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
125
|
+
if (mediaType.includes('send')) {
|
|
126
|
+
this.statsResults[mediaType].send.meanRemoteJitter = [];
|
|
127
|
+
this.statsResults[mediaType].send.meanRoundTripTime = [];
|
|
128
|
+
}
|
|
129
|
+
});
|
|
221
130
|
}
|
|
222
131
|
|
|
223
132
|
/**
|
|
@@ -233,86 +142,101 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
233
142
|
}
|
|
234
143
|
|
|
235
144
|
/**
|
|
236
|
-
* captures MQA data from
|
|
145
|
+
* captures MQA data from media connection
|
|
237
146
|
*
|
|
238
147
|
* @public
|
|
239
148
|
* @memberof StatsAnalyzer
|
|
240
149
|
* @returns {void}
|
|
241
150
|
*/
|
|
242
|
-
|
|
243
|
-
const
|
|
244
|
-
const audioSender = mqaData.intervals[0].audioTransmit[0];
|
|
245
|
-
const videoReceiver = mqaData.intervals[0].videoReceive[0];
|
|
246
|
-
const videoSender = mqaData.intervals[0].videoTransmit[0];
|
|
247
|
-
const shareSender = mqaData.intervals[0].videoTransmit[1];
|
|
248
|
-
const shareReceiver = mqaData.intervals[0].videoReceive[1];
|
|
249
|
-
|
|
250
|
-
getAudioSenderMqa({
|
|
251
|
-
audioSender,
|
|
252
|
-
statsResults: this.statsResults,
|
|
253
|
-
lastMqaDataSent: this.lastMqaDataSent,
|
|
254
|
-
});
|
|
255
|
-
getAudioReceiverMqa({
|
|
256
|
-
audioReceiver,
|
|
257
|
-
statsResults: this.statsResults,
|
|
258
|
-
lastMqaDataSent: this.lastMqaDataSent,
|
|
259
|
-
});
|
|
151
|
+
sendMqaData() {
|
|
152
|
+
const newMqa = cloneDeep(emptyMqaInterval);
|
|
260
153
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
});
|
|
266
|
-
getVideoSenderMqa({
|
|
267
|
-
videoSender,
|
|
268
|
-
statsResults: this.statsResults,
|
|
269
|
-
lastMqaDataSent: this.lastMqaDataSent,
|
|
270
|
-
});
|
|
154
|
+
Object.keys(this.statsResults).forEach((mediaType) => {
|
|
155
|
+
if (!this.lastMqaDataSent[mediaType]) {
|
|
156
|
+
this.lastMqaDataSent[mediaType] = {};
|
|
157
|
+
}
|
|
271
158
|
|
|
272
|
-
|
|
159
|
+
if (!this.lastMqaDataSent[mediaType].send && mediaType.includes('-send')) {
|
|
160
|
+
this.lastMqaDataSent[mediaType].send = {};
|
|
161
|
+
}
|
|
273
162
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
lastMqaDataSent: this.lastMqaDataSent,
|
|
278
|
-
isShareStream: true,
|
|
279
|
-
});
|
|
163
|
+
if (!this.lastMqaDataSent[mediaType].recv && mediaType.includes('-recv')) {
|
|
164
|
+
this.lastMqaDataSent[mediaType].recv = {};
|
|
165
|
+
}
|
|
280
166
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
statsResults: this.statsResults,
|
|
284
|
-
lastMqaDataSent: this.lastMqaDataSent,
|
|
285
|
-
isShareStream: true,
|
|
286
|
-
});
|
|
287
|
-
mqaData.intervals[0].intervalMetadata.peerReflexiveIP =
|
|
288
|
-
this.statsResults.connectionType.local.ipAddress[0];
|
|
167
|
+
if (mediaType.includes('audio-send') || mediaType.includes('audio-share-send')) {
|
|
168
|
+
const audioSender = cloneDeep(emptyAudioTransmit);
|
|
289
169
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
170
|
+
getAudioSenderMqa({
|
|
171
|
+
audioSender,
|
|
172
|
+
statsResults: this.statsResults,
|
|
173
|
+
lastMqaDataSent: this.lastMqaDataSent,
|
|
174
|
+
mediaType,
|
|
175
|
+
});
|
|
176
|
+
newMqa.audioTransmit.push(audioSender);
|
|
177
|
+
|
|
178
|
+
this.lastMqaDataSent[mediaType].send = cloneDeep(this.statsResults[mediaType].send);
|
|
179
|
+
} else if (mediaType.includes('audio-recv') || mediaType.includes('audio-share-recv')) {
|
|
180
|
+
const audioReceiver = cloneDeep(emptyAudioReceive);
|
|
181
|
+
|
|
182
|
+
getAudioReceiverMqa({
|
|
183
|
+
audioReceiver,
|
|
184
|
+
statsResults: this.statsResults,
|
|
185
|
+
lastMqaDataSent: this.lastMqaDataSent,
|
|
186
|
+
mediaType,
|
|
187
|
+
});
|
|
188
|
+
newMqa.audioReceive.push(audioReceiver);
|
|
189
|
+
|
|
190
|
+
this.lastMqaDataSent[mediaType].recv = cloneDeep(this.statsResults[mediaType].recv);
|
|
191
|
+
} else if (mediaType.includes('video-send') || mediaType.includes('video-share-send')) {
|
|
192
|
+
const videoSender = cloneDeep(emptyVideoTransmit);
|
|
193
|
+
|
|
194
|
+
getVideoSenderMqa({
|
|
195
|
+
videoSender,
|
|
196
|
+
statsResults: this.statsResults,
|
|
197
|
+
lastMqaDataSent: this.lastMqaDataSent,
|
|
198
|
+
mediaType,
|
|
199
|
+
});
|
|
200
|
+
newMqa.videoTransmit.push(videoSender);
|
|
201
|
+
|
|
202
|
+
this.lastMqaDataSent[mediaType].send = cloneDeep(this.statsResults[mediaType].send);
|
|
203
|
+
} else if (mediaType.includes('video-recv') || mediaType.includes('video-share-recv')) {
|
|
204
|
+
const videoReceiver = cloneDeep(emptyVideoReceive);
|
|
205
|
+
|
|
206
|
+
getVideoReceiverMqa({
|
|
207
|
+
videoReceiver,
|
|
208
|
+
statsResults: this.statsResults,
|
|
209
|
+
lastMqaDataSent: this.lastMqaDataSent,
|
|
210
|
+
mediaType,
|
|
211
|
+
});
|
|
212
|
+
newMqa.videoReceive.push(videoReceiver);
|
|
213
|
+
|
|
214
|
+
this.lastMqaDataSent[mediaType].recv = cloneDeep(this.statsResults[mediaType].recv);
|
|
215
|
+
}
|
|
303
216
|
});
|
|
304
217
|
|
|
305
|
-
|
|
306
|
-
mqaData.networkType = this.statsResults.connectionType.local.networkType;
|
|
218
|
+
newMqa.intervalMetadata.peerReflexiveIP = this.statsResults.connectionType.local.ipAddress;
|
|
307
219
|
|
|
308
|
-
|
|
220
|
+
// Adding peripheral information
|
|
221
|
+
newMqa.intervalMetadata.peripherals.push({information: _UNKNOWN_, name: MEDIA_DEVICES.SPEAKER});
|
|
222
|
+
if (this.statsResults['audio-send']) {
|
|
223
|
+
newMqa.intervalMetadata.peripherals.push({
|
|
224
|
+
information: this.statsResults['audio-send'].trackLabel || _UNKNOWN_,
|
|
225
|
+
name: MEDIA_DEVICES.MICROPHONE,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
if (this.statsResults['video-send']) {
|
|
229
|
+
newMqa.intervalMetadata.peripherals.push({
|
|
230
|
+
information: this.statsResults['video-send'].trackLabel || _UNKNOWN_,
|
|
231
|
+
name: MEDIA_DEVICES.CAMERA,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
309
234
|
|
|
310
|
-
|
|
235
|
+
newMqa.networkType = this.statsResults.connectionType.local.networkType;
|
|
311
236
|
|
|
312
|
-
|
|
313
|
-
this.lastMqaDataSent = cloneDeep(this.statsResults);
|
|
237
|
+
this.mqaSentCount += 1;
|
|
314
238
|
|
|
315
|
-
this.
|
|
239
|
+
newMqa.intervalNumber = this.mqaSentCount;
|
|
316
240
|
|
|
317
241
|
this.resetStatsResults();
|
|
318
242
|
|
|
@@ -323,23 +247,23 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
323
247
|
},
|
|
324
248
|
EVENTS.MEDIA_QUALITY,
|
|
325
249
|
{
|
|
326
|
-
data:
|
|
250
|
+
data: newMqa,
|
|
327
251
|
// @ts-ignore
|
|
328
|
-
networkType:
|
|
252
|
+
networkType: newMqa.networkType,
|
|
329
253
|
}
|
|
330
254
|
);
|
|
331
255
|
}
|
|
332
256
|
|
|
333
257
|
/**
|
|
334
|
-
* updated the
|
|
258
|
+
* updated the media connection when changed
|
|
335
259
|
*
|
|
336
260
|
* @private
|
|
337
|
-
* @memberof
|
|
338
|
-
* @param {
|
|
261
|
+
* @memberof StatsAnalyzer
|
|
262
|
+
* @param {RoapMediaConnection} mediaConnection
|
|
339
263
|
* @returns {void}
|
|
340
264
|
*/
|
|
341
|
-
|
|
342
|
-
this.
|
|
265
|
+
updateMediaConnection(mediaConnection: any) {
|
|
266
|
+
this.mediaConnection = mediaConnection;
|
|
343
267
|
}
|
|
344
268
|
|
|
345
269
|
/**
|
|
@@ -347,13 +271,13 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
347
271
|
*
|
|
348
272
|
* @public
|
|
349
273
|
* @memberof StatsAnalyzer
|
|
350
|
-
* @param {
|
|
274
|
+
* @param {RoapMediaConnection} mediaConnection
|
|
351
275
|
* @returns {Promise}
|
|
352
276
|
*/
|
|
353
|
-
public startAnalyzer(
|
|
277
|
+
public startAnalyzer(mediaConnection: any) {
|
|
354
278
|
if (!this.statsStarted) {
|
|
355
279
|
this.statsStarted = true;
|
|
356
|
-
this.
|
|
280
|
+
this.mediaConnection = mediaConnection;
|
|
357
281
|
|
|
358
282
|
return this.getStatsAndParse().then(() => {
|
|
359
283
|
this.statsInterval = setInterval(() => {
|
|
@@ -393,7 +317,7 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
393
317
|
if (sendOneLastMqa) {
|
|
394
318
|
return this.getStatsAndParse().then(() => {
|
|
395
319
|
this.sendMqaData();
|
|
396
|
-
this.
|
|
320
|
+
this.mediaConnection = null;
|
|
397
321
|
});
|
|
398
322
|
}
|
|
399
323
|
|
|
@@ -415,6 +339,17 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
415
339
|
return;
|
|
416
340
|
}
|
|
417
341
|
|
|
342
|
+
// Generate empty stats results
|
|
343
|
+
if (!this.statsResults[type]) {
|
|
344
|
+
this.statsResults[type] = {};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (isSender && !this.statsResults[type].send) {
|
|
348
|
+
this.statsResults[type].send = cloneDeep(emptySender);
|
|
349
|
+
} else if (!isSender && !this.statsResults[type].recv) {
|
|
350
|
+
this.statsResults[type].recv = cloneDeep(emptyReceiver);
|
|
351
|
+
}
|
|
352
|
+
|
|
418
353
|
switch (getStatsResult.type) {
|
|
419
354
|
case 'outbound-rtp':
|
|
420
355
|
this.processOutboundRTPResult(getStatsResult, type);
|
|
@@ -424,8 +359,7 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
424
359
|
break;
|
|
425
360
|
case 'remote-inbound-rtp':
|
|
426
361
|
case 'remote-outbound-rtp':
|
|
427
|
-
|
|
428
|
-
this.compareSentAndReceived(getStatsResult, type, isSender);
|
|
362
|
+
this.compareSentAndReceived(getStatsResult, type);
|
|
429
363
|
break;
|
|
430
364
|
case 'remotecandidate':
|
|
431
365
|
case 'remote-candidate':
|
|
@@ -446,23 +380,34 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
446
380
|
/**
|
|
447
381
|
* Filters the get stats results for types
|
|
448
382
|
* @private
|
|
449
|
-
* @param {Array}
|
|
383
|
+
* @param {Array} statsItem
|
|
450
384
|
* @param {String} type
|
|
451
385
|
* @param {boolean} isSender
|
|
452
386
|
* @returns {void}
|
|
453
387
|
*/
|
|
454
|
-
|
|
455
|
-
getStatsResults: Array<any>,
|
|
456
|
-
type: string,
|
|
457
|
-
isSender: boolean
|
|
458
|
-
) {
|
|
388
|
+
filterAndParseGetStatsResults(statsItem: any, type: string, isSender: boolean) {
|
|
459
389
|
const {types} = DEFAULT_GET_STATS_FILTER;
|
|
460
390
|
|
|
461
|
-
|
|
391
|
+
// get the successful candidate pair before parsing stats.
|
|
392
|
+
statsItem.report.forEach((report) => {
|
|
393
|
+
if (report.type === 'candidate-pair' && report.state === 'succeeded') {
|
|
394
|
+
this.successfulCandidatePair = report;
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
statsItem.report.forEach((result) => {
|
|
462
399
|
if (types.includes(result.type)) {
|
|
463
400
|
this.parseGetStatsResult(result, type, isSender);
|
|
464
401
|
}
|
|
465
402
|
});
|
|
403
|
+
|
|
404
|
+
if (this.statsResults[type]) {
|
|
405
|
+
this.statsResults[type].direction = statsItem.currentDirection;
|
|
406
|
+
this.statsResults[type].trackLabel = statsItem.localTrackLabel;
|
|
407
|
+
this.statsResults[type].csi = statsItem.csi;
|
|
408
|
+
// reset the successful candidate pair.
|
|
409
|
+
this.successfulCandidatePair = {};
|
|
410
|
+
}
|
|
466
411
|
}
|
|
467
412
|
|
|
468
413
|
/**
|
|
@@ -476,7 +421,7 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
476
421
|
return;
|
|
477
422
|
}
|
|
478
423
|
|
|
479
|
-
if (type
|
|
424
|
+
if (type.includes('audio-send')) {
|
|
480
425
|
this.statsResults[type].send.audioLevel = result.audioLevel;
|
|
481
426
|
this.statsResults[type].send.totalAudioEnergy = result.totalAudioEnergy;
|
|
482
427
|
}
|
|
@@ -511,6 +456,10 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
511
456
|
// eslint-disable-next-line no-param-reassign
|
|
512
457
|
if (currentValue === undefined) currentValue = 0;
|
|
513
458
|
|
|
459
|
+
if (!this.lastEmittedStartStopEvent[mediaType]) {
|
|
460
|
+
this.lastEmittedStartStopEvent[mediaType] = {};
|
|
461
|
+
}
|
|
462
|
+
|
|
514
463
|
const lastEmittedEvent = isLocal
|
|
515
464
|
? this.lastEmittedStartStopEvent[mediaType].local
|
|
516
465
|
: this.lastEmittedStartStopEvent[mediaType].remote;
|
|
@@ -519,7 +468,7 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
519
468
|
|
|
520
469
|
if (currentValue - previousValue > 0) {
|
|
521
470
|
newEvent = isLocal ? EVENTS.LOCAL_MEDIA_STARTED : EVENTS.REMOTE_MEDIA_STARTED;
|
|
522
|
-
} else if (currentValue === previousValue && currentValue
|
|
471
|
+
} else if (currentValue === previousValue && currentValue > 0) {
|
|
523
472
|
newEvent = isLocal ? EVENTS.LOCAL_MEDIA_STOPPED : EVENTS.REMOTE_MEDIA_STOPPED;
|
|
524
473
|
}
|
|
525
474
|
|
|
@@ -551,21 +500,29 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
551
500
|
*/
|
|
552
501
|
private compareLastStatsResult() {
|
|
553
502
|
if (this.lastStatsResults !== null && this.meetingMediaStatus) {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
503
|
+
const getCurrentStatsTotals = (keyPrefix: string, value: string): number =>
|
|
504
|
+
Object.keys(this.statsResults)
|
|
505
|
+
.filter((key) => key.startsWith(keyPrefix))
|
|
506
|
+
.reduce((prev, cur) => prev + (this.statsResults[cur]?.recv[value] || 0), 0);
|
|
507
|
+
|
|
508
|
+
const getPreviousStatsTotals = (keyPrefix: string, value: string): number =>
|
|
509
|
+
Object.keys(this.statsResults)
|
|
510
|
+
.filter((key) => key.startsWith(keyPrefix))
|
|
511
|
+
.reduce((prev, cur) => prev + (this.lastStatsResults[cur]?.recv[value] || 0), 0);
|
|
512
|
+
|
|
513
|
+
if (this.meetingMediaStatus.expected.sendAudio && this.lastStatsResults['audio-send']) {
|
|
514
|
+
// compare audio stats sent
|
|
515
|
+
// NOTE: relies on there being only one sender.
|
|
516
|
+
const currentStats = this.statsResults['audio-send'].send;
|
|
517
|
+
const previousStats = this.lastStatsResults['audio-send'].send;
|
|
562
518
|
|
|
563
519
|
if (
|
|
564
520
|
currentStats.totalPacketsSent === previousStats.totalPacketsSent ||
|
|
565
521
|
currentStats.totalPacketsSent === 0
|
|
566
522
|
) {
|
|
567
523
|
LoggerProxy.logger.info(
|
|
568
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
524
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets sent`,
|
|
525
|
+
currentStats.totalPacketsSent
|
|
569
526
|
);
|
|
570
527
|
} else {
|
|
571
528
|
if (
|
|
@@ -573,19 +530,20 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
573
530
|
currentStats.totalAudioEnergy === 0
|
|
574
531
|
) {
|
|
575
532
|
LoggerProxy.logger.info(
|
|
576
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
533
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No audio Energy present`,
|
|
534
|
+
currentStats.totalAudioEnergy
|
|
577
535
|
);
|
|
578
536
|
}
|
|
579
537
|
|
|
580
538
|
if (currentStats.audioLevel === 0) {
|
|
581
539
|
LoggerProxy.logger.info(
|
|
582
|
-
`StatsAnalyzer:index#compareLastStatsResult -->
|
|
540
|
+
`StatsAnalyzer:index#compareLastStatsResult --> audio level is 0 for the user`
|
|
583
541
|
);
|
|
584
542
|
}
|
|
585
543
|
}
|
|
586
544
|
|
|
587
545
|
this.emitStartStopEvents(
|
|
588
|
-
|
|
546
|
+
'audio',
|
|
589
547
|
previousStats.totalPacketsSent,
|
|
590
548
|
currentStats.totalPacketsSent,
|
|
591
549
|
true
|
|
@@ -594,266 +552,199 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
594
552
|
|
|
595
553
|
if (this.meetingMediaStatus.expected.receiveAudio) {
|
|
596
554
|
// compare audio stats received
|
|
597
|
-
|
|
598
|
-
|
|
555
|
+
const currentPacketsReceived = getCurrentStatsTotals('audio-recv', 'totalPacketsReceived');
|
|
556
|
+
const previousPacketsReceived = getPreviousStatsTotals(
|
|
557
|
+
'audio-recv',
|
|
558
|
+
'totalPacketsReceived'
|
|
559
|
+
);
|
|
560
|
+
const currentSamplesReceived = getCurrentStatsTotals('audio-recv', 'totalSamplesReceived');
|
|
561
|
+
const previousSamplesReceived = getPreviousStatsTotals(
|
|
562
|
+
'audio-recv',
|
|
563
|
+
'totalSamplesReceived'
|
|
564
|
+
);
|
|
599
565
|
|
|
600
|
-
if (
|
|
601
|
-
currentStats.totalPacketsReceived === previousStats.totalPacketsReceived ||
|
|
602
|
-
currentStats.totalPacketsReceived === 0
|
|
603
|
-
) {
|
|
566
|
+
if (currentPacketsReceived === previousPacketsReceived || currentPacketsReceived === 0) {
|
|
604
567
|
LoggerProxy.logger.info(
|
|
605
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
568
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets received`,
|
|
569
|
+
currentPacketsReceived
|
|
606
570
|
);
|
|
607
571
|
} else if (
|
|
608
|
-
|
|
609
|
-
|
|
572
|
+
currentSamplesReceived === previousSamplesReceived ||
|
|
573
|
+
currentSamplesReceived === 0
|
|
610
574
|
) {
|
|
611
575
|
LoggerProxy.logger.info(
|
|
612
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
576
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No audio samples received`,
|
|
577
|
+
currentSamplesReceived
|
|
613
578
|
);
|
|
614
579
|
}
|
|
615
580
|
|
|
616
|
-
this.emitStartStopEvents(
|
|
617
|
-
mediaType,
|
|
618
|
-
previousStats.totalPacketsReceived,
|
|
619
|
-
currentStats.totalPacketsReceived,
|
|
620
|
-
false
|
|
621
|
-
);
|
|
581
|
+
this.emitStartStopEvents('audio', previousPacketsReceived, currentPacketsReceived, false);
|
|
622
582
|
}
|
|
623
583
|
|
|
624
|
-
|
|
625
|
-
if (this.meetingMediaStatus.expected.sendVideo) {
|
|
584
|
+
if (this.meetingMediaStatus.expected.sendVideo && this.lastStatsResults['video-send']) {
|
|
626
585
|
// compare video stats sent
|
|
627
|
-
currentStats = this.statsResults[
|
|
628
|
-
previousStats = this.lastStatsResults[
|
|
586
|
+
const currentStats = this.statsResults['video-send'].send;
|
|
587
|
+
const previousStats = this.lastStatsResults['video-send'].send;
|
|
629
588
|
|
|
630
589
|
if (
|
|
631
590
|
currentStats.totalPacketsSent === previousStats.totalPacketsSent ||
|
|
632
591
|
currentStats.totalPacketsSent === 0
|
|
633
592
|
) {
|
|
634
593
|
LoggerProxy.logger.info(
|
|
635
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
594
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No video RTP packets sent`,
|
|
595
|
+
currentStats.totalPacketsSent
|
|
636
596
|
);
|
|
637
|
-
} else
|
|
597
|
+
} else {
|
|
638
598
|
if (
|
|
639
599
|
currentStats.framesEncoded === previousStats.framesEncoded ||
|
|
640
600
|
currentStats.framesEncoded === 0
|
|
641
|
-
) {
|
|
642
|
-
this.lastEmittedStartStopEvent[mediaType].local = EVENTS.NO_VIDEO_ENCODED;
|
|
643
|
-
LoggerProxy.logger.info(
|
|
644
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} Frames Encoded`
|
|
645
|
-
);
|
|
646
|
-
this.emit(
|
|
647
|
-
{
|
|
648
|
-
file: 'statsAnalyzer',
|
|
649
|
-
function: 'compareLastStatsResult',
|
|
650
|
-
},
|
|
651
|
-
EVENTS.NO_VIDEO_ENCODED,
|
|
652
|
-
{
|
|
653
|
-
mediaType,
|
|
654
|
-
}
|
|
655
|
-
);
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
if (
|
|
659
|
-
this.statsResults.resolutions[mediaType].send.framesSent ===
|
|
660
|
-
this.lastStatsResults.resolutions[mediaType].send.framesSent ||
|
|
661
|
-
this.statsResults.resolutions[mediaType].send.framesSent === 0
|
|
662
601
|
) {
|
|
663
602
|
LoggerProxy.logger.info(
|
|
664
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
603
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No video Frames Encoded`,
|
|
604
|
+
currentStats.framesEncoded
|
|
665
605
|
);
|
|
666
606
|
}
|
|
667
607
|
|
|
668
|
-
// Video is encoded but frames are not sent
|
|
669
608
|
if (
|
|
670
|
-
|
|
671
|
-
|
|
609
|
+
this.statsResults['video-send'].send.framesSent ===
|
|
610
|
+
this.lastStatsResults['video-send'].send.framesSent ||
|
|
611
|
+
this.statsResults['video-send'].send.framesSent === 0
|
|
672
612
|
) {
|
|
673
|
-
this.lastEmittedStartStopEvent[mediaType].local = EVENTS.NO_FRAMES_SENT;
|
|
674
613
|
LoggerProxy.logger.info(
|
|
675
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
676
|
-
|
|
677
|
-
this.emit(
|
|
678
|
-
{
|
|
679
|
-
file: 'statsAnalyzer',
|
|
680
|
-
function: 'compareLastStatsResult',
|
|
681
|
-
},
|
|
682
|
-
EVENTS.NO_FRAMES_SENT,
|
|
683
|
-
{
|
|
684
|
-
mediaType,
|
|
685
|
-
}
|
|
614
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No video Frames sent`,
|
|
615
|
+
this.statsResults['video-send'].send.framesSent
|
|
686
616
|
);
|
|
687
617
|
}
|
|
688
618
|
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
previousStats.framesSent,
|
|
692
|
-
currentStats.framesSent,
|
|
693
|
-
true
|
|
694
|
-
);
|
|
619
|
+
|
|
620
|
+
this.emitStartStopEvents('video', previousStats.framesSent, currentStats.framesSent, true);
|
|
695
621
|
}
|
|
696
622
|
|
|
697
623
|
if (this.meetingMediaStatus.expected.receiveVideo) {
|
|
698
|
-
// compare video stats
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
)
|
|
624
|
+
// compare video stats received
|
|
625
|
+
const currentPacketsReceived = getCurrentStatsTotals('video-recv', 'totalPacketsReceived');
|
|
626
|
+
const previousPacketsReceived = getPreviousStatsTotals(
|
|
627
|
+
'video-recv',
|
|
628
|
+
'totalPacketsReceived'
|
|
629
|
+
);
|
|
630
|
+
const currentFramesReceived = getCurrentStatsTotals('video-recv', 'framesReceived');
|
|
631
|
+
const previousFramesReceived = getPreviousStatsTotals('video-recv', 'framesReceived');
|
|
632
|
+
const currentFramesDecoded = getCurrentStatsTotals('video-recv', 'framesDecoded');
|
|
633
|
+
const previousFramesDecoded = getPreviousStatsTotals('video-recv', 'framesDecoded');
|
|
634
|
+
const currentFramesDropped = getCurrentStatsTotals('video-recv', 'framesDropped');
|
|
635
|
+
const previousFramesDropped = getPreviousStatsTotals('video-recv', 'framesDropped');
|
|
636
|
+
|
|
637
|
+
if (currentPacketsReceived === previousPacketsReceived || currentPacketsReceived === 0) {
|
|
707
638
|
LoggerProxy.logger.info(
|
|
708
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
639
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No video RTP packets received`,
|
|
640
|
+
currentPacketsReceived
|
|
709
641
|
);
|
|
710
642
|
} else {
|
|
711
|
-
if (
|
|
712
|
-
this.statsResults.resolutions[mediaType].recv.framesReceived ===
|
|
713
|
-
this.lastStatsResults.resolutions[mediaType].recv.framesReceived ||
|
|
714
|
-
this.statsResults.resolutions[mediaType].recv.framesReceived === 0
|
|
715
|
-
) {
|
|
643
|
+
if (currentFramesReceived === previousFramesReceived || currentFramesReceived === 0) {
|
|
716
644
|
LoggerProxy.logger.info(
|
|
717
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
645
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No video frames received`,
|
|
646
|
+
currentFramesReceived
|
|
718
647
|
);
|
|
719
648
|
}
|
|
720
649
|
|
|
721
|
-
if (
|
|
722
|
-
this.statsResults[mediaType].recv.framesDecoded ===
|
|
723
|
-
this.lastStatsResults[mediaType].recv.framesDecoded ||
|
|
724
|
-
this.statsResults.resolutions[mediaType].send.framesDecoded === 0
|
|
725
|
-
) {
|
|
650
|
+
if (currentFramesDecoded === previousFramesDecoded || currentFramesDecoded === 0) {
|
|
726
651
|
LoggerProxy.logger.info(
|
|
727
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
652
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No video frames decoded`,
|
|
653
|
+
currentFramesDecoded
|
|
728
654
|
);
|
|
729
655
|
}
|
|
730
656
|
|
|
731
|
-
if (
|
|
732
|
-
this.statsResults.resolutions[mediaType].recv.framesDropped -
|
|
733
|
-
this.lastStatsResults.resolutions[mediaType].recv.framesDropped >
|
|
734
|
-
10
|
|
735
|
-
) {
|
|
657
|
+
if (currentFramesDropped - previousFramesDropped > 10) {
|
|
736
658
|
LoggerProxy.logger.info(
|
|
737
|
-
`StatsAnalyzer:index#compareLastStatsResult -->
|
|
659
|
+
`StatsAnalyzer:index#compareLastStatsResult --> video frames are getting dropped`,
|
|
660
|
+
currentFramesDropped - previousFramesDropped
|
|
738
661
|
);
|
|
739
662
|
}
|
|
740
663
|
}
|
|
741
664
|
|
|
742
|
-
this.emitStartStopEvents(
|
|
743
|
-
mediaType,
|
|
744
|
-
previousStats.framesDecoded,
|
|
745
|
-
currentStats.framesDecoded,
|
|
746
|
-
false
|
|
747
|
-
);
|
|
665
|
+
this.emitStartStopEvents('video', previousFramesDecoded, currentFramesDecoded, false);
|
|
748
666
|
}
|
|
749
667
|
|
|
750
|
-
|
|
751
|
-
if (this.meetingMediaStatus.expected.sendShare) {
|
|
668
|
+
if (this.meetingMediaStatus.expected.sendShare && this.lastStatsResults['video-share-send']) {
|
|
752
669
|
// compare share stats sent
|
|
753
670
|
|
|
754
|
-
currentStats = this.statsResults[
|
|
755
|
-
previousStats = this.lastStatsResults[
|
|
671
|
+
const currentStats = this.statsResults['video-share-send'].send;
|
|
672
|
+
const previousStats = this.lastStatsResults['video-share-send'].send;
|
|
756
673
|
|
|
757
674
|
if (
|
|
758
675
|
currentStats.totalPacketsSent === previousStats.totalPacketsSent ||
|
|
759
676
|
currentStats.totalPacketsSent === 0
|
|
760
677
|
) {
|
|
761
678
|
LoggerProxy.logger.info(
|
|
762
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
679
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No share RTP packets sent`,
|
|
680
|
+
currentStats.totalPacketsSent
|
|
763
681
|
);
|
|
764
|
-
} else
|
|
682
|
+
} else {
|
|
765
683
|
if (
|
|
766
684
|
currentStats.framesEncoded === previousStats.framesEncoded ||
|
|
767
685
|
currentStats.framesEncoded === 0
|
|
768
686
|
) {
|
|
769
|
-
this.lastEmittedStartStopEvent[mediaType].local = EVENTS.NO_VIDEO_ENCODED;
|
|
770
687
|
LoggerProxy.logger.info(
|
|
771
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
772
|
-
|
|
773
|
-
this.emit(
|
|
774
|
-
{
|
|
775
|
-
file: 'statsAnalyzer',
|
|
776
|
-
function: 'compareLastStatsResult',
|
|
777
|
-
},
|
|
778
|
-
EVENTS.NO_VIDEO_ENCODED,
|
|
779
|
-
{
|
|
780
|
-
mediaType,
|
|
781
|
-
}
|
|
688
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No share frames getting encoded`,
|
|
689
|
+
currentStats.framesEncoded
|
|
782
690
|
);
|
|
783
691
|
}
|
|
784
692
|
|
|
785
693
|
if (
|
|
786
|
-
this.statsResults
|
|
787
|
-
this.lastStatsResults
|
|
788
|
-
this.statsResults
|
|
694
|
+
this.statsResults['video-share-send'].send.framesSent ===
|
|
695
|
+
this.lastStatsResults['video-share-send'].send.framesSent ||
|
|
696
|
+
this.statsResults['video-share-send'].send.framesSent === 0
|
|
789
697
|
) {
|
|
790
698
|
LoggerProxy.logger.info(
|
|
791
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
792
|
-
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
// Share video is encoded but frames are not sent
|
|
796
|
-
if (
|
|
797
|
-
currentStats.framesEncoded !== previousStats.framesEncoded &&
|
|
798
|
-
(currentStats.framesSent === previousStats.framesSent || currentStats.framesSent === 0)
|
|
799
|
-
) {
|
|
800
|
-
this.lastEmittedStartStopEvent[mediaType].local = EVENTS.NO_FRAMES_SENT;
|
|
801
|
-
LoggerProxy.logger.info(
|
|
802
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} Frames sent even though frames are being encoded`
|
|
803
|
-
);
|
|
804
|
-
this.emit(
|
|
805
|
-
{
|
|
806
|
-
file: 'statsAnalyzer',
|
|
807
|
-
function: 'compareLastStatsResult',
|
|
808
|
-
},
|
|
809
|
-
EVENTS.NO_FRAMES_SENT,
|
|
810
|
-
{
|
|
811
|
-
mediaType,
|
|
812
|
-
}
|
|
699
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No share frames sent`,
|
|
700
|
+
this.statsResults['video-share-send'].send.framesSent
|
|
813
701
|
);
|
|
814
702
|
}
|
|
815
703
|
}
|
|
704
|
+
}
|
|
816
705
|
|
|
706
|
+
if (this.meetingMediaStatus.expected.sendShare) {
|
|
817
707
|
// TODO:need to check receive share value
|
|
818
|
-
// compare share stats
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
708
|
+
// compare share stats received
|
|
709
|
+
const currentPacketsReceived = getCurrentStatsTotals(
|
|
710
|
+
'video-share-recv',
|
|
711
|
+
'totalPacketsReceived'
|
|
712
|
+
);
|
|
713
|
+
const previousPacketsReceived = getPreviousStatsTotals(
|
|
714
|
+
'video-share-recv',
|
|
715
|
+
'totalPacketsReceived'
|
|
716
|
+
);
|
|
717
|
+
const currentFramesReceived = getCurrentStatsTotals('video-share-recv', 'framesReceived');
|
|
718
|
+
const previousFramesReceived = getPreviousStatsTotals('video-share-recv', 'framesReceived');
|
|
719
|
+
const currentFramesDecoded = getCurrentStatsTotals('video-share-recv', 'framesDecoded');
|
|
720
|
+
const previousFramesDecoded = getPreviousStatsTotals('video-share-recv', 'framesDecoded');
|
|
721
|
+
const currentFramesDropped = getCurrentStatsTotals('video-share-recv', 'framesDropped');
|
|
722
|
+
const previousFramesDropped = getPreviousStatsTotals('video-share-recv', 'framesDropped');
|
|
723
|
+
|
|
724
|
+
if (currentPacketsReceived === previousPacketsReceived || currentPacketsReceived === 0) {
|
|
826
725
|
LoggerProxy.logger.info(
|
|
827
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
726
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No share RTP packets received`,
|
|
727
|
+
currentPacketsReceived
|
|
828
728
|
);
|
|
829
729
|
} else {
|
|
830
|
-
if (
|
|
831
|
-
this.statsResults.resolutions[mediaType].recv.framesReceived ===
|
|
832
|
-
this.lastStatsResults.resolutions[mediaType].recv.framesReceived ||
|
|
833
|
-
this.statsResults.resolutions[mediaType].recv.framesReceived === 0
|
|
834
|
-
) {
|
|
730
|
+
if (currentFramesReceived === previousFramesReceived || currentFramesReceived === 0) {
|
|
835
731
|
LoggerProxy.logger.info(
|
|
836
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
732
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No share frames received`,
|
|
733
|
+
currentFramesReceived
|
|
837
734
|
);
|
|
838
735
|
}
|
|
839
736
|
|
|
840
|
-
if (
|
|
841
|
-
this.statsResults[mediaType].recv.framesDecoded ===
|
|
842
|
-
this.lastStatsResults[mediaType].recv.framesDecoded ||
|
|
843
|
-
this.statsResults.resolutions[mediaType].send.framesDecoded === 0
|
|
844
|
-
) {
|
|
737
|
+
if (currentFramesDecoded === previousFramesDecoded || currentFramesDecoded === 0) {
|
|
845
738
|
LoggerProxy.logger.info(
|
|
846
|
-
`StatsAnalyzer:index#compareLastStatsResult --> No
|
|
739
|
+
`StatsAnalyzer:index#compareLastStatsResult --> No share frames decoded`,
|
|
740
|
+
currentFramesDecoded
|
|
847
741
|
);
|
|
848
742
|
}
|
|
849
743
|
|
|
850
|
-
if (
|
|
851
|
-
this.statsResults.resolutions[mediaType].recv.framesDropped -
|
|
852
|
-
this.lastStatsResults.resolutions[mediaType].recv.framesDropped >
|
|
853
|
-
10
|
|
854
|
-
) {
|
|
744
|
+
if (currentFramesDropped - previousFramesDropped > 10) {
|
|
855
745
|
LoggerProxy.logger.info(
|
|
856
|
-
`StatsAnalyzer:index#compareLastStatsResult -->
|
|
746
|
+
`StatsAnalyzer:index#compareLastStatsResult --> share frames are getting dropped`,
|
|
747
|
+
currentFramesDropped - previousFramesDropped
|
|
857
748
|
);
|
|
858
749
|
}
|
|
859
750
|
}
|
|
@@ -873,13 +764,16 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
873
764
|
* @returns {Promise}
|
|
874
765
|
*/
|
|
875
766
|
private getStatsAndParse() {
|
|
876
|
-
if (!this.
|
|
767
|
+
if (!this.mediaConnection) {
|
|
877
768
|
return Promise.resolve();
|
|
878
769
|
}
|
|
879
770
|
|
|
880
|
-
if (
|
|
771
|
+
if (
|
|
772
|
+
this.mediaConnection &&
|
|
773
|
+
this.mediaConnection.getConnectionState() === ConnectionState.Failed
|
|
774
|
+
) {
|
|
881
775
|
LoggerProxy.logger.trace(
|
|
882
|
-
'StatsAnalyzer:index#getStatsAndParse -->
|
|
776
|
+
'StatsAnalyzer:index#getStatsAndParse --> media connection is in failed state'
|
|
883
777
|
);
|
|
884
778
|
|
|
885
779
|
return Promise.resolve();
|
|
@@ -887,43 +781,49 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
887
781
|
|
|
888
782
|
LoggerProxy.logger.trace('StatsAnalyzer:index#getStatsAndParse --> Collecting Stats');
|
|
889
783
|
|
|
890
|
-
return
|
|
891
|
-
|
|
892
|
-
this.filterAndParseGetStatsResults(
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
784
|
+
return this.mediaConnection.getTransceiverStats().then((transceiverStats) => {
|
|
785
|
+
transceiverStats.video.receivers.forEach((receiver, i) =>
|
|
786
|
+
this.filterAndParseGetStatsResults(receiver, `video-recv-${i}`, false)
|
|
787
|
+
);
|
|
788
|
+
transceiverStats.audio.receivers.forEach((receiver, i) =>
|
|
789
|
+
this.filterAndParseGetStatsResults(receiver, `audio-recv-${i}`, false)
|
|
790
|
+
);
|
|
791
|
+
transceiverStats.screenShareVideo.receivers.forEach((receiver, i) =>
|
|
792
|
+
this.filterAndParseGetStatsResults(receiver, `video-share-recv-${i}`, false)
|
|
793
|
+
);
|
|
794
|
+
transceiverStats.screenShareAudio.receivers.forEach((receiver, i) =>
|
|
795
|
+
this.filterAndParseGetStatsResults(receiver, `audio-share-recv-${i}`, false)
|
|
796
|
+
);
|
|
797
|
+
|
|
798
|
+
transceiverStats.video.senders.forEach((sender, i) => {
|
|
799
|
+
if (i > 0) {
|
|
800
|
+
throw new Error('Stats Analyzer does not support multiple senders.');
|
|
801
|
+
}
|
|
802
|
+
this.filterAndParseGetStatsResults(sender, 'video-send', true);
|
|
803
|
+
});
|
|
804
|
+
transceiverStats.audio.senders.forEach((sender, i) => {
|
|
805
|
+
if (i > 0) {
|
|
806
|
+
throw new Error('Stats Analyzer does not support multiple senders.');
|
|
807
|
+
}
|
|
808
|
+
this.filterAndParseGetStatsResults(sender, 'audio-send', true);
|
|
809
|
+
});
|
|
810
|
+
transceiverStats.screenShareVideo.senders.forEach((sender, i) => {
|
|
811
|
+
if (i > 0) {
|
|
812
|
+
throw new Error('Stats Analyzer does not support multiple senders.');
|
|
813
|
+
}
|
|
814
|
+
this.filterAndParseGetStatsResults(sender, 'video-share-send', true);
|
|
815
|
+
});
|
|
816
|
+
transceiverStats.screenShareAudio.senders.forEach((sender, i) => {
|
|
817
|
+
if (i > 0) {
|
|
818
|
+
throw new Error('Stats Analyzer does not support multiple senders.');
|
|
819
|
+
}
|
|
820
|
+
this.filterAndParseGetStatsResults(sender, 'audio-share-send', true);
|
|
821
|
+
});
|
|
822
|
+
|
|
924
823
|
this.compareLastStatsResult();
|
|
925
824
|
|
|
926
825
|
// Save the last results to compare with the current
|
|
826
|
+
// DO Deep copy, for some reason it takes the reference all the time rather then old value set
|
|
927
827
|
this.lastStatsResults = JSON.parse(JSON.stringify(this.statsResults));
|
|
928
828
|
|
|
929
829
|
LoggerProxy.logger.trace(
|
|
@@ -936,51 +836,27 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
936
836
|
* Processes OutboundRTP stats result and stores
|
|
937
837
|
* @private
|
|
938
838
|
* @param {*} result
|
|
939
|
-
* @param {*}
|
|
839
|
+
* @param {*} mediaType
|
|
940
840
|
* @returns {void}
|
|
941
841
|
*/
|
|
942
|
-
private processOutboundRTPResult(result: any,
|
|
943
|
-
const mediaType = type || STATS.AUDIO_CORRELATE;
|
|
842
|
+
private processOutboundRTPResult(result: any, mediaType: any) {
|
|
944
843
|
const sendrecvType = STATS.SEND_DIRECTION;
|
|
945
844
|
|
|
946
|
-
this.processTrackResult(result, type, sendrecvType);
|
|
947
845
|
if (result.bytesSent) {
|
|
948
|
-
|
|
846
|
+
const kilobytes = 0;
|
|
949
847
|
|
|
950
|
-
if (
|
|
951
|
-
this.statsResults
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
this.statsResults
|
|
955
|
-
}
|
|
956
|
-
if (!this.statsResults.internal[mediaType][sendrecvType].keyFramesEncoded) {
|
|
957
|
-
this.statsResults.internal[mediaType][sendrecvType].keyFramesEncoded =
|
|
958
|
-
result.keyFramesEncoded;
|
|
848
|
+
if (result.frameWidth && result.frameHeight) {
|
|
849
|
+
this.statsResults[mediaType][sendrecvType].width = result.frameWidth;
|
|
850
|
+
this.statsResults[mediaType][sendrecvType].height = result.frameHeight;
|
|
851
|
+
this.statsResults[mediaType][sendrecvType].framesSent = result.framesSent;
|
|
852
|
+
this.statsResults[mediaType][sendrecvType].hugeFramesSent = result.hugeFramesSent;
|
|
959
853
|
}
|
|
960
854
|
|
|
961
|
-
const bytes =
|
|
962
|
-
result.bytesSent - this.statsResults.internal[mediaType][sendrecvType].prevBytesSent;
|
|
963
|
-
|
|
964
|
-
this.statsResults.internal[mediaType][sendrecvType].prevBytesSent = result.bytesSent;
|
|
965
|
-
|
|
966
|
-
kilobytes = bytes / 1024;
|
|
967
|
-
|
|
968
855
|
this.statsResults[mediaType][sendrecvType].availableBandwidth = kilobytes.toFixed(1);
|
|
969
|
-
this.statsResults[mediaType].bytesSent = kilobytes;
|
|
970
|
-
this.statsResults[mediaType][sendrecvType].framesEncoded =
|
|
971
|
-
result.framesEncoded - this.statsResults.internal[mediaType][sendrecvType].framesEncoded;
|
|
972
|
-
this.statsResults[mediaType][sendrecvType].keyFramesEncoded =
|
|
973
|
-
result.keyFramesEncoded -
|
|
974
|
-
this.statsResults.internal[mediaType][sendrecvType].keyFramesEncoded;
|
|
975
|
-
this.statsResults.internal[mediaType].outboundRtpId = result.id;
|
|
976
|
-
|
|
977
|
-
if (!this.statsResults.internal[mediaType][sendrecvType].packetsSent) {
|
|
978
|
-
this.statsResults.internal[mediaType][sendrecvType].packetsSent = result.packetsSent;
|
|
979
|
-
}
|
|
980
856
|
|
|
981
|
-
this.statsResults[mediaType][sendrecvType].
|
|
982
|
-
|
|
983
|
-
this.statsResults
|
|
857
|
+
this.statsResults[mediaType][sendrecvType].framesEncoded = result.framesEncoded;
|
|
858
|
+
this.statsResults[mediaType][sendrecvType].keyFramesEncoded = result.keyFramesEncoded;
|
|
859
|
+
this.statsResults[mediaType][sendrecvType].packetsSent = result.packetsSent;
|
|
984
860
|
|
|
985
861
|
// Data saved to send MQA metrics
|
|
986
862
|
|
|
@@ -1010,81 +886,58 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
1010
886
|
* Processes InboundRTP stats result and stores
|
|
1011
887
|
* @private
|
|
1012
888
|
* @param {*} result
|
|
1013
|
-
* @param {*}
|
|
889
|
+
* @param {*} mediaType
|
|
1014
890
|
* @returns {void}
|
|
1015
891
|
*/
|
|
1016
|
-
private processInboundRTPResult(result: any,
|
|
1017
|
-
const mediaType = type || STATS.AUDIO_CORRELATE;
|
|
892
|
+
private processInboundRTPResult(result: any, mediaType: any) {
|
|
1018
893
|
const sendrecvType = STATS.RECEIVE_DIRECTION;
|
|
1019
894
|
|
|
1020
|
-
this.processTrackResult(result, type, sendrecvType);
|
|
1021
895
|
if (result.bytesReceived) {
|
|
1022
896
|
let kilobytes = 0;
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
this.statsResults
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
if (!this.statsResults.internal[mediaType][sendrecvType].packetsLost) {
|
|
1034
|
-
this.statsResults.internal[mediaType][sendrecvType].packetsLost = result.packetsLost;
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
if (!this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived) {
|
|
1038
|
-
this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived =
|
|
1039
|
-
result.packetsReceived;
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
if (!this.statsResults.internal[mediaType][sendrecvType].lastPacketReceivedTimestamp) {
|
|
1043
|
-
this.statsResults.internal[mediaType][sendrecvType].lastPacketReceivedTimestamp =
|
|
1044
|
-
result.lastPacketReceivedTimestamp;
|
|
897
|
+
const receiveSlot = this.receiveSlotCallback(result.ssrc);
|
|
898
|
+
const idAndCsi = receiveSlot
|
|
899
|
+
? `id: "${receiveSlot.id || ''}"${receiveSlot.csi ? ` and csi: ${receiveSlot.csi}` : ''}`
|
|
900
|
+
: '';
|
|
901
|
+
|
|
902
|
+
if (result.frameWidth && result.frameHeight) {
|
|
903
|
+
this.statsResults[mediaType][sendrecvType].width = result.frameWidth;
|
|
904
|
+
this.statsResults[mediaType][sendrecvType].height = result.frameHeight;
|
|
905
|
+
this.statsResults[mediaType][sendrecvType].framesReceived = result.framesReceived;
|
|
1045
906
|
}
|
|
1046
907
|
|
|
1047
908
|
const bytes =
|
|
1048
|
-
result.bytesReceived -
|
|
1049
|
-
this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived;
|
|
1050
|
-
|
|
1051
|
-
this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived = result.bytesReceived;
|
|
909
|
+
result.bytesReceived - this.statsResults[mediaType][sendrecvType].totalBytesReceived;
|
|
1052
910
|
|
|
1053
911
|
kilobytes = bytes / 1024;
|
|
1054
912
|
this.statsResults[mediaType][sendrecvType].availableBandwidth = kilobytes.toFixed(1);
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
result.packetsLost - this.statsResults.internal[mediaType][sendrecvType].packetsLost;
|
|
1061
|
-
if (this.statsResults[mediaType][sendrecvType].currentPacketsLost < 0) {
|
|
1062
|
-
this.statsResults[mediaType][sendrecvType].currentPacketsLost = 0;
|
|
913
|
+
|
|
914
|
+
let currentPacketsLost =
|
|
915
|
+
result.packetsLost - this.statsResults[mediaType][sendrecvType].totalPacketsLost;
|
|
916
|
+
if (currentPacketsLost < 0) {
|
|
917
|
+
currentPacketsLost = 0;
|
|
1063
918
|
}
|
|
1064
919
|
|
|
1065
|
-
|
|
1066
|
-
result.packetsReceived -
|
|
1067
|
-
|
|
1068
|
-
this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived =
|
|
1069
|
-
result.packetsReceived;
|
|
920
|
+
const currentPacketsReceived =
|
|
921
|
+
result.packetsReceived - this.statsResults[mediaType][sendrecvType].totalPacketsReceived;
|
|
922
|
+
this.statsResults[mediaType][sendrecvType].totalPacketsReceived = result.packetsReceived;
|
|
1070
923
|
|
|
1071
|
-
if (
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
924
|
+
if (currentPacketsReceived === 0) {
|
|
925
|
+
if (receiveSlot) {
|
|
926
|
+
LoggerProxy.logger.info(
|
|
927
|
+
`StatsAnalyzer:index#processInboundRTPResult --> No packets received for receive slot ${idAndCsi}`,
|
|
928
|
+
currentPacketsReceived
|
|
929
|
+
);
|
|
930
|
+
}
|
|
1076
931
|
}
|
|
1077
932
|
|
|
1078
933
|
// Check the over all packet Lost ratio
|
|
1079
934
|
this.statsResults[mediaType][sendrecvType].currentPacketLossRatio =
|
|
1080
|
-
|
|
1081
|
-
?
|
|
1082
|
-
(this.statsResults[mediaType][sendrecvType].packetsReceived +
|
|
1083
|
-
this.statsResults[mediaType][sendrecvType].currentPacketsLost)
|
|
935
|
+
currentPacketsLost > 0
|
|
936
|
+
? currentPacketsLost / (currentPacketsReceived + currentPacketsLost)
|
|
1084
937
|
: 0;
|
|
1085
938
|
if (this.statsResults[mediaType][sendrecvType].currentPacketLossRatio > 3) {
|
|
1086
939
|
LoggerProxy.logger.info(
|
|
1087
|
-
|
|
940
|
+
`StatsAnalyzer:index#processInboundRTPResult --> Packets getting lost from the receiver with slot ${idAndCsi}`,
|
|
1088
941
|
this.statsResults[mediaType][sendrecvType].currentPacketLossRatio
|
|
1089
942
|
);
|
|
1090
943
|
}
|
|
@@ -1144,126 +997,48 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
1144
997
|
if (!result || !result.id) {
|
|
1145
998
|
return;
|
|
1146
999
|
}
|
|
1147
|
-
const RemoteCandidateType = {};
|
|
1148
|
-
const RemoteTransport = {};
|
|
1149
|
-
const RemoteIpAddress = {};
|
|
1150
|
-
const RemoteNetworkType = {};
|
|
1151
|
-
|
|
1152
|
-
if (!result.id) return;
|
|
1153
|
-
|
|
1154
|
-
const sendRecvType = isSender ? STATS.SEND_DIRECTION : STATS.RECEIVE_DIRECTION;
|
|
1155
|
-
const ipType = isRemote ? STATS.REMOTE : STATS.LOCAL;
|
|
1156
|
-
|
|
1157
|
-
if (!RemoteCandidateType[result.id]) {
|
|
1158
|
-
RemoteCandidateType[result.id] = [];
|
|
1159
|
-
}
|
|
1160
1000
|
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
if (!RemoteIpAddress[result.id]) {
|
|
1166
|
-
RemoteIpAddress[result.id] = [];
|
|
1167
|
-
}
|
|
1168
|
-
if (!RemoteNetworkType[result.id]) {
|
|
1169
|
-
RemoteNetworkType[result.id] = [];
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
if (
|
|
1173
|
-
result.candidateType &&
|
|
1174
|
-
RemoteCandidateType[result.id].indexOf(result.candidateType) === -1
|
|
1175
|
-
) {
|
|
1176
|
-
RemoteCandidateType[result.id].push(result.candidateType);
|
|
1001
|
+
// We only care about the successful local candidate
|
|
1002
|
+
if (this.successfulCandidatePair?.localCandidateId !== result.id) {
|
|
1003
|
+
return;
|
|
1177
1004
|
}
|
|
1178
1005
|
|
|
1179
|
-
|
|
1180
|
-
|
|
1006
|
+
let transport;
|
|
1007
|
+
if (result.relayProtocol) {
|
|
1008
|
+
transport = result.relayProtocol.toUpperCase();
|
|
1009
|
+
} else if (result.protocol) {
|
|
1010
|
+
transport = result.protocol.toUpperCase();
|
|
1181
1011
|
}
|
|
1182
1012
|
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
RemoteIpAddress[result.id].indexOf(`${result.ip}:${result.portNumber}`) === -1
|
|
1186
|
-
) {
|
|
1187
|
-
RemoteIpAddress[result.id].push(`${result.ip}`); // TODO: Add ports
|
|
1188
|
-
}
|
|
1013
|
+
const sendRecvType = isSender ? STATS.SEND_DIRECTION : STATS.RECEIVE_DIRECTION;
|
|
1014
|
+
const ipType = isRemote ? STATS.REMOTE : STATS.LOCAL;
|
|
1189
1015
|
|
|
1190
|
-
if (
|
|
1191
|
-
|
|
1016
|
+
if (!this.statsResults.candidates) {
|
|
1017
|
+
this.statsResults.candidates = {};
|
|
1192
1018
|
}
|
|
1193
1019
|
|
|
1194
|
-
this.statsResults.
|
|
1195
|
-
candidateType:
|
|
1196
|
-
ipAddress:
|
|
1020
|
+
this.statsResults.candidates[result.id] = {
|
|
1021
|
+
candidateType: result.candidateType,
|
|
1022
|
+
ipAddress: result.ip, // TODO: add ports
|
|
1197
1023
|
portNumber: result.port,
|
|
1198
|
-
networkType:
|
|
1024
|
+
networkType: result.networkType,
|
|
1199
1025
|
priority: result.priority,
|
|
1200
|
-
transport
|
|
1026
|
+
transport,
|
|
1201
1027
|
timestamp: result.time,
|
|
1202
1028
|
id: result.id,
|
|
1203
1029
|
type: result.type,
|
|
1204
1030
|
};
|
|
1205
1031
|
|
|
1206
|
-
this.statsResults.connectionType[ipType].candidateType =
|
|
1207
|
-
this.statsResults.connectionType[ipType].ipAddress =
|
|
1032
|
+
this.statsResults.connectionType[ipType].candidateType = result.candidateType;
|
|
1033
|
+
this.statsResults.connectionType[ipType].ipAddress = result.ipAddress;
|
|
1208
1034
|
|
|
1209
1035
|
this.statsResults.connectionType[ipType].networkType =
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
: RemoteNetworkType[result.id][0];
|
|
1213
|
-
this.statsResults.connectionType[ipType].transport = RemoteTransport[result.id];
|
|
1036
|
+
result.networkType === NETWORK_TYPE.VPN ? NETWORK_TYPE.UNKNOWN : result.networkType;
|
|
1037
|
+
this.statsResults.connectionType[ipType].transport = transport;
|
|
1214
1038
|
|
|
1215
1039
|
this.statsResults[type][sendRecvType].totalRoundTripTime = result.totalRoundTripTime;
|
|
1216
1040
|
};
|
|
1217
1041
|
|
|
1218
|
-
/**
|
|
1219
|
-
* Process Track results
|
|
1220
|
-
*
|
|
1221
|
-
* @private
|
|
1222
|
-
* @param {*} result
|
|
1223
|
-
* @param {*} mediaType
|
|
1224
|
-
* @param {*} sendrecvType
|
|
1225
|
-
* @returns {void}
|
|
1226
|
-
* @memberof StatsAnalyzer
|
|
1227
|
-
*/
|
|
1228
|
-
private processTrackResult(result: any, mediaType: any, sendrecvType: any) {
|
|
1229
|
-
if (!result || mediaType === STATS.AUDIO_CORRELATE) {
|
|
1230
|
-
return;
|
|
1231
|
-
}
|
|
1232
|
-
if (result.type !== 'inbound-rtp' && result.type !== 'outbound-rtp') {
|
|
1233
|
-
return;
|
|
1234
|
-
}
|
|
1235
|
-
if (result.frameWidth && result.frameHeight) {
|
|
1236
|
-
this.statsResults.resolutions[mediaType][sendrecvType].width = result.frameWidth;
|
|
1237
|
-
this.statsResults.resolutions[mediaType][sendrecvType].height = result.frameHeight;
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
|
-
if (sendrecvType === STATS.RECEIVE_DIRECTION) {
|
|
1241
|
-
this.statsResults.resolutions[mediaType][sendrecvType].framesReceived = result.framesReceived;
|
|
1242
|
-
this.statsResults.resolutions[mediaType][sendrecvType].framesDecoded = result.framesDecoded;
|
|
1243
|
-
this.statsResults.resolutions[mediaType][sendrecvType].framesDropped = result.framesDropped;
|
|
1244
|
-
} else if (sendrecvType === STATS.SEND_DIRECTION) {
|
|
1245
|
-
this.statsResults.resolutions[mediaType][sendrecvType].framesSent = result.framesSent;
|
|
1246
|
-
this.statsResults.resolutions[mediaType][sendrecvType].hugeFramesSent = result.hugeFramesSent;
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
if (result.trackIdentifier && mediaType !== STATS.AUDIO_CORRELATE) {
|
|
1250
|
-
this.statsResults.resolutions[mediaType][sendrecvType].trackIdentifier =
|
|
1251
|
-
result.trackIdentifier;
|
|
1252
|
-
|
|
1253
|
-
const jitterBufferDelay = result && result.jitterBufferDelay;
|
|
1254
|
-
const jitterBufferEmittedCount = result && result.jitterBufferEmittedCount;
|
|
1255
|
-
|
|
1256
|
-
this.statsResults.resolutions[mediaType][sendrecvType].avgJitterDelay =
|
|
1257
|
-
jitterBufferEmittedCount && +jitterBufferDelay / +jitterBufferEmittedCount;
|
|
1258
|
-
|
|
1259
|
-
// Used to calculate the jitter
|
|
1260
|
-
this.statsResults.resolutions[mediaType][sendrecvType].jitterBufferDelay =
|
|
1261
|
-
result.jitterBufferDelay;
|
|
1262
|
-
this.statsResults.resolutions[mediaType][sendrecvType].jitterBufferEmittedCount =
|
|
1263
|
-
result.jitterBufferEmittedCount;
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
1042
|
/**
|
|
1268
1043
|
*
|
|
1269
1044
|
* @private
|
|
@@ -1272,21 +1047,17 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
1272
1047
|
* @returns {void}
|
|
1273
1048
|
* @memberof StatsAnalyzer
|
|
1274
1049
|
*/
|
|
1275
|
-
|
|
1276
|
-
|
|
1050
|
+
compareSentAndReceived(result, type) {
|
|
1051
|
+
// Don't compare on transceivers without a sender.
|
|
1052
|
+
if (!type || !this.statsResults[type].send) {
|
|
1277
1053
|
return;
|
|
1278
1054
|
}
|
|
1279
1055
|
|
|
1280
1056
|
const mediaType = type;
|
|
1281
1057
|
|
|
1282
|
-
if (!this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver) {
|
|
1283
|
-
this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver = result.packetsLost;
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
1058
|
const currentPacketLoss =
|
|
1287
|
-
result.packetsLost - this.statsResults
|
|
1059
|
+
result.packetsLost - this.statsResults[mediaType].send.totalPacketsLostOnReceiver;
|
|
1288
1060
|
|
|
1289
|
-
this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver = result.packetsLost;
|
|
1290
1061
|
this.statsResults[mediaType].send.packetsLostOnReceiver = currentPacketLoss;
|
|
1291
1062
|
this.statsResults[mediaType].send.totalPacketsLostOnReceiver = result.packetsLost;
|
|
1292
1063
|
|