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