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