@webex/plugin-meetings 2.4.2 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/meeting/index.js +166 -0
- package/dist/meeting/index.js.map +1 -1
- package/dist/metrics/constants.js +5 -1
- package/dist/metrics/constants.js.map +1 -1
- package/package.json +7 -6
- package/src/meeting/index.js +95 -0
- package/src/metrics/constants.js +5 -1
- package/test/unit/spec/meeting/index.js +198 -1
|
@@ -46,7 +46,11 @@ var BEHAVIORAL_METRICS = {
|
|
|
46
46
|
PEERCONNECTION_FAILURE: 'js_sdk_peerConnection_failures',
|
|
47
47
|
INVALID_ICE_CANDIDATE: 'js_sdk_invalid_ice_candidate',
|
|
48
48
|
UPLOAD_LOGS_FAILURE: 'js_sdk_upload_logs_failure',
|
|
49
|
-
RECEIVE_TRANSCRIPTION_FAILURE: 'js_sdk_receive_transcription_failure'
|
|
49
|
+
RECEIVE_TRANSCRIPTION_FAILURE: 'js_sdk_receive_transcription_failure',
|
|
50
|
+
ENABLE_BNR_SUCCESS: 'js_sdk_enable_bnr_success',
|
|
51
|
+
ENABLE_BNR_FAILURE: 'js_sdk_enable_bnr_failure',
|
|
52
|
+
DISABLE_BNR_SUCCESS: 'js_sdk_disable_bnr_success',
|
|
53
|
+
DISABLE_BNR_FAILURE: 'js_sdk_disable_bnr_failure'
|
|
50
54
|
};
|
|
51
55
|
exports.default = BEHAVIORAL_METRICS;
|
|
52
56
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["BEHAVIORAL_METRICS","MEETINGS_REGISTRATION_FAILED","MEETINGS_REGISTRATION_SUCCESS","MERCURY_CONNECTION_FAILURE","MERCURY_CONNECTION_RESTORED","JOIN_SUCCESS","JOIN_FAILURE","ADD_MEDIA_SUCCESS","ADD_MEDIA_FAILURE","CONNECTION_SUCCESS","CONNECTION_FAILURE","MEETING_LEAVE_FAILURE","MEETING_END_ALL_FAILURE","MEETING_END_ALL_INITIATED","GET_USER_MEDIA_FAILURE","GET_DISPLAY_MEDIA_FAILURE","JOIN_WITH_MEDIA_FAILURE","DISCONNECT_DUE_TO_INACTIVITY","MEETING_MEDIA_INACTIVE","MEETING_RECONNECT_FAILURE","MEETING_MAX_REJOIN_FAILURE","MEETING_SHARE_FAILURE","MEETING_START_WHITEBOARD_SHARE_FAILURE","MEETING_STOP_WHITEBOARD_SHARE_FAILURE","MUTE_AUDIO_FAILURE","MUTE_VIDEO_FAILURE","SET_MEETING_QUALITY_FAILURE","STOP_FLOOR_REQUEST_FAILURE","ADD_DIAL_IN_FAILURE","ADD_DIAL_OUT_FAILURE","UPDATE_MEDIA_FAILURE","UNMUTE_AUDIO_FAILURE","UNMUTE_VIDEO_FAILURE","ROAP_ANSWER_FAILURE","ROAP_GLARE_CONDITION","PEERCONNECTION_FAILURE","INVALID_ICE_CANDIDATE","UPLOAD_LOGS_FAILURE","RECEIVE_TRANSCRIPTION_FAILURE"],"sources":["constants.js"],"sourcesContent":["\n// Metrics constants ----------------------------------------------------------\n\nconst BEHAVIORAL_METRICS = {\n MEETINGS_REGISTRATION_FAILED: 'js_sdk_meetings_registration_failed',\n MEETINGS_REGISTRATION_SUCCESS: 'js_sdk_meetings_registration_success',\n MERCURY_CONNECTION_FAILURE: 'js_sdk_mercury_connection_failure',\n MERCURY_CONNECTION_RESTORED: 'js_sdk_mercury_connection_restored',\n JOIN_SUCCESS: 'js_sdk_join_success',\n JOIN_FAILURE: 'js_sdk_join_failures',\n ADD_MEDIA_SUCCESS: 'js_sdk_add_media_success',\n ADD_MEDIA_FAILURE: 'js_sdk_add_media_failures',\n CONNECTION_SUCCESS: 'js_sdk_connection_success',\n CONNECTION_FAILURE: 'js_sdk_connection_failures',\n MEETING_LEAVE_FAILURE: 'js_sdk_meeting_leave_failure',\n MEETING_END_ALL_FAILURE: 'js_sdk_meeting_end_for_all_failure',\n MEETING_END_ALL_INITIATED: 'js_sdk_meeting_end_for_all_initiated',\n GET_USER_MEDIA_FAILURE: 'js_sdk_get_user_media_failures',\n GET_DISPLAY_MEDIA_FAILURE: 'js_sdk_get_display_media_failures',\n JOIN_WITH_MEDIA_FAILURE: 'js_sdk_join_with_media_failures',\n\n DISCONNECT_DUE_TO_INACTIVITY: 'js_sdk_disconnect_due_to_inactivity',\n MEETING_MEDIA_INACTIVE: 'js_sdk_meeting_media_inactive',\n MEETING_RECONNECT_FAILURE: 'js_sdk_meeting_reconnect_failures',\n MEETING_MAX_REJOIN_FAILURE: 'js_sdk_meeting_max_rejoin_failure',\n MEETING_SHARE_FAILURE: 'js_sdk_meeting_share_failures',\n MEETING_START_WHITEBOARD_SHARE_FAILURE: 'js_sdk_meeting_start_whiteboard_share_failures',\n MEETING_STOP_WHITEBOARD_SHARE_FAILURE: 'js_sdk_meeting_stop_whiteboard_share_failures',\n MUTE_AUDIO_FAILURE: 'js_sdk_mute_audio_failures',\n MUTE_VIDEO_FAILURE: 'js_sdk_mute_video_failures',\n SET_MEETING_QUALITY_FAILURE: 'js_sdk_set_meeting_quality_failures',\n STOP_FLOOR_REQUEST_FAILURE: 'js_sdk_stop_floor_request_failures',\n ADD_DIAL_IN_FAILURE: 'js_sdk_add_dial_in_failure',\n ADD_DIAL_OUT_FAILURE: 'js_sdk_add_dial_out_failure',\n UPDATE_MEDIA_FAILURE: 'js_sdk_update_media_failures',\n UNMUTE_AUDIO_FAILURE: 'js_sdk_unmute_audio_failures',\n UNMUTE_VIDEO_FAILURE: 'js_sdk_unmute_video_failures',\n ROAP_ANSWER_FAILURE: 'js_sdk_roap_answer_failures',\n ROAP_GLARE_CONDITION: 'js_sdk_roap_glar_condition',\n PEERCONNECTION_FAILURE: 'js_sdk_peerConnection_failures',\n INVALID_ICE_CANDIDATE: 'js_sdk_invalid_ice_candidate',\n UPLOAD_LOGS_FAILURE: 'js_sdk_upload_logs_failure',\n RECEIVE_TRANSCRIPTION_FAILURE: 'js_sdk_receive_transcription_failure'\n};\n\n\nexport {BEHAVIORAL_METRICS as default};\n"],"mappings":";;;;;;;;;AACA;AAEA,IAAMA,kBAAkB,GAAG;EACzBC,4BAA4B,EAAE,qCADL;EAEzBC,6BAA6B,EAAE,sCAFN;EAGzBC,0BAA0B,EAAE,mCAHH;EAIzBC,2BAA2B,EAAE,oCAJJ;EAKzBC,YAAY,EAAE,qBALW;EAMzBC,YAAY,EAAE,sBANW;EAOzBC,iBAAiB,EAAE,0BAPM;EAQzBC,iBAAiB,EAAE,2BARM;EASzBC,kBAAkB,EAAE,2BATK;EAUzBC,kBAAkB,EAAE,4BAVK;EAWzBC,qBAAqB,EAAE,8BAXE;EAYzBC,uBAAuB,EAAE,oCAZA;EAazBC,yBAAyB,EAAE,sCAbF;EAczBC,sBAAsB,EAAE,gCAdC;EAezBC,yBAAyB,EAAE,mCAfF;EAgBzBC,uBAAuB,EAAE,iCAhBA;EAkBzBC,4BAA4B,EAAE,qCAlBL;EAmBzBC,sBAAsB,EAAE,+BAnBC;EAoBzBC,yBAAyB,EAAE,mCApBF;EAqBzBC,0BAA0B,EAAE,mCArBH;EAsBzBC,qBAAqB,EAAE,+BAtBE;EAuBzBC,sCAAsC,EAAE,gDAvBf;EAwBzBC,qCAAqC,EAAE,+CAxBd;EAyBzBC,kBAAkB,EAAE,4BAzBK;EA0BzBC,kBAAkB,EAAE,4BA1BK;EA2BzBC,2BAA2B,EAAE,qCA3BJ;EA4BzBC,0BAA0B,EAAE,oCA5BH;EA6BzBC,mBAAmB,EAAE,4BA7BI;EA8BzBC,oBAAoB,EAAE,6BA9BG;EA+BzBC,oBAAoB,EAAE,8BA/BG;EAgCzBC,oBAAoB,EAAE,8BAhCG;EAiCzBC,oBAAoB,EAAE,8BAjCG;EAkCzBC,mBAAmB,EAAE,6BAlCI;EAmCzBC,oBAAoB,EAAE,4BAnCG;EAoCzBC,sBAAsB,EAAE,gCApCC;EAqCzBC,qBAAqB,EAAE,8BArCE;EAsCzBC,mBAAmB,EAAE,4BAtCI;EAuCzBC,6BAA6B,EAAE;
|
|
1
|
+
{"version":3,"names":["BEHAVIORAL_METRICS","MEETINGS_REGISTRATION_FAILED","MEETINGS_REGISTRATION_SUCCESS","MERCURY_CONNECTION_FAILURE","MERCURY_CONNECTION_RESTORED","JOIN_SUCCESS","JOIN_FAILURE","ADD_MEDIA_SUCCESS","ADD_MEDIA_FAILURE","CONNECTION_SUCCESS","CONNECTION_FAILURE","MEETING_LEAVE_FAILURE","MEETING_END_ALL_FAILURE","MEETING_END_ALL_INITIATED","GET_USER_MEDIA_FAILURE","GET_DISPLAY_MEDIA_FAILURE","JOIN_WITH_MEDIA_FAILURE","DISCONNECT_DUE_TO_INACTIVITY","MEETING_MEDIA_INACTIVE","MEETING_RECONNECT_FAILURE","MEETING_MAX_REJOIN_FAILURE","MEETING_SHARE_FAILURE","MEETING_START_WHITEBOARD_SHARE_FAILURE","MEETING_STOP_WHITEBOARD_SHARE_FAILURE","MUTE_AUDIO_FAILURE","MUTE_VIDEO_FAILURE","SET_MEETING_QUALITY_FAILURE","STOP_FLOOR_REQUEST_FAILURE","ADD_DIAL_IN_FAILURE","ADD_DIAL_OUT_FAILURE","UPDATE_MEDIA_FAILURE","UNMUTE_AUDIO_FAILURE","UNMUTE_VIDEO_FAILURE","ROAP_ANSWER_FAILURE","ROAP_GLARE_CONDITION","PEERCONNECTION_FAILURE","INVALID_ICE_CANDIDATE","UPLOAD_LOGS_FAILURE","RECEIVE_TRANSCRIPTION_FAILURE","ENABLE_BNR_SUCCESS","ENABLE_BNR_FAILURE","DISABLE_BNR_SUCCESS","DISABLE_BNR_FAILURE"],"sources":["constants.js"],"sourcesContent":["\n// Metrics constants ----------------------------------------------------------\n\nconst BEHAVIORAL_METRICS = {\n MEETINGS_REGISTRATION_FAILED: 'js_sdk_meetings_registration_failed',\n MEETINGS_REGISTRATION_SUCCESS: 'js_sdk_meetings_registration_success',\n MERCURY_CONNECTION_FAILURE: 'js_sdk_mercury_connection_failure',\n MERCURY_CONNECTION_RESTORED: 'js_sdk_mercury_connection_restored',\n JOIN_SUCCESS: 'js_sdk_join_success',\n JOIN_FAILURE: 'js_sdk_join_failures',\n ADD_MEDIA_SUCCESS: 'js_sdk_add_media_success',\n ADD_MEDIA_FAILURE: 'js_sdk_add_media_failures',\n CONNECTION_SUCCESS: 'js_sdk_connection_success',\n CONNECTION_FAILURE: 'js_sdk_connection_failures',\n MEETING_LEAVE_FAILURE: 'js_sdk_meeting_leave_failure',\n MEETING_END_ALL_FAILURE: 'js_sdk_meeting_end_for_all_failure',\n MEETING_END_ALL_INITIATED: 'js_sdk_meeting_end_for_all_initiated',\n GET_USER_MEDIA_FAILURE: 'js_sdk_get_user_media_failures',\n GET_DISPLAY_MEDIA_FAILURE: 'js_sdk_get_display_media_failures',\n JOIN_WITH_MEDIA_FAILURE: 'js_sdk_join_with_media_failures',\n\n DISCONNECT_DUE_TO_INACTIVITY: 'js_sdk_disconnect_due_to_inactivity',\n MEETING_MEDIA_INACTIVE: 'js_sdk_meeting_media_inactive',\n MEETING_RECONNECT_FAILURE: 'js_sdk_meeting_reconnect_failures',\n MEETING_MAX_REJOIN_FAILURE: 'js_sdk_meeting_max_rejoin_failure',\n MEETING_SHARE_FAILURE: 'js_sdk_meeting_share_failures',\n MEETING_START_WHITEBOARD_SHARE_FAILURE: 'js_sdk_meeting_start_whiteboard_share_failures',\n MEETING_STOP_WHITEBOARD_SHARE_FAILURE: 'js_sdk_meeting_stop_whiteboard_share_failures',\n MUTE_AUDIO_FAILURE: 'js_sdk_mute_audio_failures',\n MUTE_VIDEO_FAILURE: 'js_sdk_mute_video_failures',\n SET_MEETING_QUALITY_FAILURE: 'js_sdk_set_meeting_quality_failures',\n STOP_FLOOR_REQUEST_FAILURE: 'js_sdk_stop_floor_request_failures',\n ADD_DIAL_IN_FAILURE: 'js_sdk_add_dial_in_failure',\n ADD_DIAL_OUT_FAILURE: 'js_sdk_add_dial_out_failure',\n UPDATE_MEDIA_FAILURE: 'js_sdk_update_media_failures',\n UNMUTE_AUDIO_FAILURE: 'js_sdk_unmute_audio_failures',\n UNMUTE_VIDEO_FAILURE: 'js_sdk_unmute_video_failures',\n ROAP_ANSWER_FAILURE: 'js_sdk_roap_answer_failures',\n ROAP_GLARE_CONDITION: 'js_sdk_roap_glar_condition',\n PEERCONNECTION_FAILURE: 'js_sdk_peerConnection_failures',\n INVALID_ICE_CANDIDATE: 'js_sdk_invalid_ice_candidate',\n UPLOAD_LOGS_FAILURE: 'js_sdk_upload_logs_failure',\n RECEIVE_TRANSCRIPTION_FAILURE: 'js_sdk_receive_transcription_failure',\n ENABLE_BNR_SUCCESS: 'js_sdk_enable_bnr_success',\n ENABLE_BNR_FAILURE: 'js_sdk_enable_bnr_failure',\n DISABLE_BNR_SUCCESS: 'js_sdk_disable_bnr_success',\n DISABLE_BNR_FAILURE: 'js_sdk_disable_bnr_failure'\n};\n\n\nexport {BEHAVIORAL_METRICS as default};\n"],"mappings":";;;;;;;;;AACA;AAEA,IAAMA,kBAAkB,GAAG;EACzBC,4BAA4B,EAAE,qCADL;EAEzBC,6BAA6B,EAAE,sCAFN;EAGzBC,0BAA0B,EAAE,mCAHH;EAIzBC,2BAA2B,EAAE,oCAJJ;EAKzBC,YAAY,EAAE,qBALW;EAMzBC,YAAY,EAAE,sBANW;EAOzBC,iBAAiB,EAAE,0BAPM;EAQzBC,iBAAiB,EAAE,2BARM;EASzBC,kBAAkB,EAAE,2BATK;EAUzBC,kBAAkB,EAAE,4BAVK;EAWzBC,qBAAqB,EAAE,8BAXE;EAYzBC,uBAAuB,EAAE,oCAZA;EAazBC,yBAAyB,EAAE,sCAbF;EAczBC,sBAAsB,EAAE,gCAdC;EAezBC,yBAAyB,EAAE,mCAfF;EAgBzBC,uBAAuB,EAAE,iCAhBA;EAkBzBC,4BAA4B,EAAE,qCAlBL;EAmBzBC,sBAAsB,EAAE,+BAnBC;EAoBzBC,yBAAyB,EAAE,mCApBF;EAqBzBC,0BAA0B,EAAE,mCArBH;EAsBzBC,qBAAqB,EAAE,+BAtBE;EAuBzBC,sCAAsC,EAAE,gDAvBf;EAwBzBC,qCAAqC,EAAE,+CAxBd;EAyBzBC,kBAAkB,EAAE,4BAzBK;EA0BzBC,kBAAkB,EAAE,4BA1BK;EA2BzBC,2BAA2B,EAAE,qCA3BJ;EA4BzBC,0BAA0B,EAAE,oCA5BH;EA6BzBC,mBAAmB,EAAE,4BA7BI;EA8BzBC,oBAAoB,EAAE,6BA9BG;EA+BzBC,oBAAoB,EAAE,8BA/BG;EAgCzBC,oBAAoB,EAAE,8BAhCG;EAiCzBC,oBAAoB,EAAE,8BAjCG;EAkCzBC,mBAAmB,EAAE,6BAlCI;EAmCzBC,oBAAoB,EAAE,4BAnCG;EAoCzBC,sBAAsB,EAAE,gCApCC;EAqCzBC,qBAAqB,EAAE,8BArCE;EAsCzBC,mBAAmB,EAAE,4BAtCI;EAuCzBC,6BAA6B,EAAE,sCAvCN;EAwCzBC,kBAAkB,EAAE,2BAxCK;EAyCzBC,kBAAkB,EAAE,2BAzCK;EA0CzBC,mBAAmB,EAAE,4BA1CI;EA2CzBC,mBAAmB,EAAE;AA3CI,CAA3B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/plugin-meetings",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"contributors": [
|
|
@@ -24,20 +24,21 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@babel/runtime-corejs2": "^7.14.8",
|
|
27
|
-
"@webex/webex-core": "2.
|
|
28
|
-
"@webex/internal-plugin-mercury": "2.
|
|
29
|
-
"@webex/internal-plugin-conversation": "2.
|
|
27
|
+
"@webex/webex-core": "2.7.0",
|
|
28
|
+
"@webex/internal-plugin-mercury": "2.7.0",
|
|
29
|
+
"@webex/internal-plugin-conversation": "2.7.0",
|
|
30
30
|
"webrtc-adapter": "^7.7.0",
|
|
31
31
|
"lodash": "^4.17.21",
|
|
32
32
|
"uuid": "^3.3.2",
|
|
33
33
|
"global": "^4.4.0",
|
|
34
34
|
"ip-anonymize": "^0.1.0",
|
|
35
|
-
"@webex/common": "2.
|
|
35
|
+
"@webex/common": "2.7.0",
|
|
36
36
|
"bowser": "^2.11.0",
|
|
37
37
|
"sdp-transform": "^2.12.0",
|
|
38
38
|
"readable-stream": "^3.6.0",
|
|
39
|
-
"@webex/common-timers": "2.
|
|
39
|
+
"@webex/common-timers": "2.7.0",
|
|
40
40
|
"btoa": "^1.2.1",
|
|
41
|
+
"@webex/internal-media-core": "^0.0.4-beta",
|
|
41
42
|
"javascript-state-machine": "^3.1.0",
|
|
42
43
|
"envify": "^4.1.0"
|
|
43
44
|
}
|
package/src/meeting/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import uuid from 'uuid';
|
|
2
2
|
import {cloneDeep, isEqual, pick} from 'lodash';
|
|
3
3
|
import {StatelessWebexPlugin} from '@webex/webex-core';
|
|
4
|
+
import {Media as WebRTCMedia} from '@webex/internal-media-core';
|
|
4
5
|
|
|
5
6
|
import {
|
|
6
7
|
MeetingNotActiveError, createMeetingsError, UserInLobbyError,
|
|
@@ -83,6 +84,7 @@ import RoapCollection from '../roap/collection';
|
|
|
83
84
|
|
|
84
85
|
import InMeetingActions from './in-meeting-actions';
|
|
85
86
|
|
|
87
|
+
|
|
86
88
|
const {isBrowser} = BrowserDetection();
|
|
87
89
|
|
|
88
90
|
const logRequest = (request, {header = '', success = '', failure = ''}) => {
|
|
@@ -5739,4 +5741,97 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5739
5741
|
this.transcription = undefined;
|
|
5740
5742
|
}
|
|
5741
5743
|
};
|
|
5744
|
+
|
|
5745
|
+
/**
|
|
5746
|
+
* enableBNR API
|
|
5747
|
+
* @returns {Promise<Boolean>}
|
|
5748
|
+
* @public
|
|
5749
|
+
* @memberof Meeting
|
|
5750
|
+
*/
|
|
5751
|
+
async enableBNR() {
|
|
5752
|
+
LoggerProxy.logger.info('Meeting:index#enableBNR. Enable BNR called');
|
|
5753
|
+
let isSuccess = false;
|
|
5754
|
+
|
|
5755
|
+
try {
|
|
5756
|
+
if (typeof this.mediaProperties === 'undefined' || typeof this.mediaProperties.audioTrack === 'undefined') {
|
|
5757
|
+
throw new Error("Meeting doesn't have an audioTrack attached");
|
|
5758
|
+
}
|
|
5759
|
+
this.mediaProperties.audioTrack = await WebRTCMedia.Effects.BNR.enableBNR(this.mediaProperties.audioTrack);
|
|
5760
|
+
const audioStream = MediaUtil.createMediaStream([this.mediaProperties.audioTrack]);
|
|
5761
|
+
|
|
5762
|
+
LoggerProxy.logger.info('Meeting:index#enableBNR. BNR enabled track obtained from WebRTC & sent to updateAudio');
|
|
5763
|
+
await this.updateAudio({
|
|
5764
|
+
sendAudio: true,
|
|
5765
|
+
receiveAudio: true,
|
|
5766
|
+
stream: audioStream
|
|
5767
|
+
});
|
|
5768
|
+
this.isBnrEnabled = true;
|
|
5769
|
+
isSuccess = true;
|
|
5770
|
+
Metrics.sendBehavioralMetric(
|
|
5771
|
+
BEHAVIORAL_METRICS.ENABLE_BNR_SUCCESS,
|
|
5772
|
+
);
|
|
5773
|
+
}
|
|
5774
|
+
catch (error) {
|
|
5775
|
+
LoggerProxy.logger.error(`Meeting:index#enableBNR. ${error}`);
|
|
5776
|
+
|
|
5777
|
+
Metrics.sendBehavioralMetric(
|
|
5778
|
+
BEHAVIORAL_METRICS.ENABLE_BNR_FAILURE,
|
|
5779
|
+
{
|
|
5780
|
+
reason: error.message,
|
|
5781
|
+
stack: error.stack
|
|
5782
|
+
}
|
|
5783
|
+
);
|
|
5784
|
+
|
|
5785
|
+
throw error;
|
|
5786
|
+
}
|
|
5787
|
+
|
|
5788
|
+
return isSuccess;
|
|
5789
|
+
}
|
|
5790
|
+
|
|
5791
|
+
/**
|
|
5792
|
+
* disableBNR API
|
|
5793
|
+
* @returns {Promise<Boolean>}
|
|
5794
|
+
* @public
|
|
5795
|
+
* @memberof Meeting
|
|
5796
|
+
*/
|
|
5797
|
+
async disableBNR() {
|
|
5798
|
+
LoggerProxy.logger.info('Meeting:index#disableBNR. Disable BNR called');
|
|
5799
|
+
let isSuccess = false;
|
|
5800
|
+
|
|
5801
|
+
try {
|
|
5802
|
+
if (typeof this.mediaProperties === 'undefined' || typeof this.mediaProperties.audioTrack === 'undefined') {
|
|
5803
|
+
throw new Error("Meeting doesn't have an audioTrack attached");
|
|
5804
|
+
}
|
|
5805
|
+
this.mediaProperties.audioTrack = WebRTCMedia.Effects.BNR.disableBNR(this.mediaProperties.audioTrack);
|
|
5806
|
+
const audioStream = MediaUtil.createMediaStream([this.mediaProperties.audioTrack]);
|
|
5807
|
+
|
|
5808
|
+
LoggerProxy.logger.info('Meeting:index#disableBNR. Raw media track obtained from WebRTC & sent to updateAudio');
|
|
5809
|
+
await this.updateAudio({
|
|
5810
|
+
sendAudio: true,
|
|
5811
|
+
receiveAudio: true,
|
|
5812
|
+
stream: audioStream
|
|
5813
|
+
});
|
|
5814
|
+
this.isBnrEnabled = false;
|
|
5815
|
+
isSuccess = true;
|
|
5816
|
+
|
|
5817
|
+
Metrics.sendBehavioralMetric(
|
|
5818
|
+
BEHAVIORAL_METRICS.DISABLE_BNR_SUCCESS
|
|
5819
|
+
);
|
|
5820
|
+
}
|
|
5821
|
+
catch (error) {
|
|
5822
|
+
LoggerProxy.logger.error(`Meeting:index#disableBNR. ${error}`);
|
|
5823
|
+
|
|
5824
|
+
Metrics.sendBehavioralMetric(
|
|
5825
|
+
BEHAVIORAL_METRICS.DISABLE_BNR_FAILURE,
|
|
5826
|
+
{
|
|
5827
|
+
reason: error.message,
|
|
5828
|
+
stack: error.stack
|
|
5829
|
+
}
|
|
5830
|
+
);
|
|
5831
|
+
|
|
5832
|
+
throw error;
|
|
5833
|
+
}
|
|
5834
|
+
|
|
5835
|
+
return isSuccess;
|
|
5836
|
+
}
|
|
5742
5837
|
}
|
package/src/metrics/constants.js
CHANGED
|
@@ -40,7 +40,11 @@ const BEHAVIORAL_METRICS = {
|
|
|
40
40
|
PEERCONNECTION_FAILURE: 'js_sdk_peerConnection_failures',
|
|
41
41
|
INVALID_ICE_CANDIDATE: 'js_sdk_invalid_ice_candidate',
|
|
42
42
|
UPLOAD_LOGS_FAILURE: 'js_sdk_upload_logs_failure',
|
|
43
|
-
RECEIVE_TRANSCRIPTION_FAILURE: 'js_sdk_receive_transcription_failure'
|
|
43
|
+
RECEIVE_TRANSCRIPTION_FAILURE: 'js_sdk_receive_transcription_failure',
|
|
44
|
+
ENABLE_BNR_SUCCESS: 'js_sdk_enable_bnr_success',
|
|
45
|
+
ENABLE_BNR_FAILURE: 'js_sdk_enable_bnr_failure',
|
|
46
|
+
DISABLE_BNR_SUCCESS: 'js_sdk_disable_bnr_success',
|
|
47
|
+
DISABLE_BNR_FAILURE: 'js_sdk_disable_bnr_failure'
|
|
44
48
|
};
|
|
45
49
|
|
|
46
50
|
|
|
@@ -74,6 +74,13 @@ describe('plugin-meetings', () => {
|
|
|
74
74
|
debug: () => {}
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
+
beforeEach(() => {
|
|
78
|
+
sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
79
|
+
});
|
|
80
|
+
afterEach(() => {
|
|
81
|
+
sinon.restore();
|
|
82
|
+
});
|
|
83
|
+
|
|
77
84
|
before(() => {
|
|
78
85
|
const MediaStream = {
|
|
79
86
|
getVideoTracks: () => [{
|
|
@@ -105,6 +112,9 @@ describe('plugin-meetings', () => {
|
|
|
105
112
|
groupId: '29d9339cc77bffdd24cb69ee80f6d3200481099bcd0f29267558672de0430777',
|
|
106
113
|
}
|
|
107
114
|
])),
|
|
115
|
+
getSupportedConstraints: sinon.stub().returns({
|
|
116
|
+
sampleRate: true
|
|
117
|
+
})
|
|
108
118
|
},
|
|
109
119
|
});
|
|
110
120
|
|
|
@@ -445,6 +455,194 @@ describe('plugin-meetings', () => {
|
|
|
445
455
|
});
|
|
446
456
|
});
|
|
447
457
|
});
|
|
458
|
+
describe('BNR', () => {
|
|
459
|
+
class FakeMediaStream {
|
|
460
|
+
constructor() {
|
|
461
|
+
this.active = false;
|
|
462
|
+
this.id = '5146425f-c240-48cc-b86b-27d422988fb7';
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
addTrack = () => undefined;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
class FakeAudioContext {
|
|
469
|
+
constructor() {
|
|
470
|
+
this.state = 'running';
|
|
471
|
+
this.baseLatency = 0.005333333333333333;
|
|
472
|
+
this.currentTime = 2.7946666666666666;
|
|
473
|
+
this.sampleRate = 48000;
|
|
474
|
+
this.audioWorklet = {
|
|
475
|
+
addModule: async () => undefined,
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
onstatechange = null;
|
|
480
|
+
|
|
481
|
+
createMediaStreamSource() {
|
|
482
|
+
return {
|
|
483
|
+
connect: () => undefined,
|
|
484
|
+
mediaStream: {
|
|
485
|
+
getAudioTracks() {
|
|
486
|
+
// eslint-disable-next-line no-undef
|
|
487
|
+
return [new MediaStreamTrack()];
|
|
488
|
+
},
|
|
489
|
+
},
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
createMediaStreamDestination() {
|
|
494
|
+
return {
|
|
495
|
+
stream: {
|
|
496
|
+
getAudioTracks() {
|
|
497
|
+
// eslint-disable-next-line no-undef
|
|
498
|
+
return [new MediaStreamTrack()];
|
|
499
|
+
},
|
|
500
|
+
},
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
class FakeAudioWorkletNode {
|
|
506
|
+
constructor() {
|
|
507
|
+
this.port = {
|
|
508
|
+
postMessage: () => undefined,
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
connect() {
|
|
513
|
+
/* placeholder method */
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
class FakeMediaStreamTrack {
|
|
518
|
+
constructor() {
|
|
519
|
+
this.kind = 'audio';
|
|
520
|
+
this.enabled = true;
|
|
521
|
+
this.label = 'Default - MacBook Pro Microphone (Built-in)';
|
|
522
|
+
this.muted = false;
|
|
523
|
+
this.readyState = 'live';
|
|
524
|
+
this.contentHint = '';
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
Object.defineProperty(global, 'MediaStream', {
|
|
528
|
+
writable: true,
|
|
529
|
+
value: FakeMediaStream,
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
Object.defineProperty(global, 'AudioContext', {
|
|
533
|
+
writable: true,
|
|
534
|
+
value: FakeAudioContext,
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
Object.defineProperty(global, 'AudioWorkletNode', {
|
|
538
|
+
writable: true,
|
|
539
|
+
value: FakeAudioWorkletNode,
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
Object.defineProperty(global, 'MediaStreamTrack', {
|
|
543
|
+
writable: true,
|
|
544
|
+
value: FakeMediaStreamTrack,
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
beforeEach(async () => {
|
|
548
|
+
meeting.canUpdateMedia = sinon.stub().returns(true);
|
|
549
|
+
MeetingUtil.validateOptions = sinon.stub().returns(Promise.resolve());
|
|
550
|
+
MeetingUtil.updateTransceiver = sinon.stub();
|
|
551
|
+
const fakeMediaTrack = () => ({
|
|
552
|
+
stop: () => {},
|
|
553
|
+
readyState: 'live',
|
|
554
|
+
getSettings: () => ({
|
|
555
|
+
sampleRate: 48000
|
|
556
|
+
})
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
meeting.getMediaStreams = sinon.stub().returns(Promise.resolve());
|
|
560
|
+
sinon.replace(meeting, 'addMedia', () => {
|
|
561
|
+
sinon.stub(meeting.mediaProperties, 'audioTrack').value(fakeMediaTrack());
|
|
562
|
+
});
|
|
563
|
+
await meeting.getMediaStreams();
|
|
564
|
+
await meeting.addMedia();
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
describe('#enableBNR', () => {
|
|
568
|
+
it('should have #enableBnr', () => {
|
|
569
|
+
assert.exists(meeting.enableBNR);
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
describe('before audio attached to meeting', () => {
|
|
573
|
+
it('should throw no audio error', async () => {
|
|
574
|
+
await meeting.enableBNR().catch((err) => {
|
|
575
|
+
assert.equal(err.toString(), 'Error: Meeting doesn\'t have an audioTrack attached');
|
|
576
|
+
});
|
|
577
|
+
});
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
describe('after audio attached to meeting', () => {
|
|
581
|
+
it('should return true for appropriate sample rate', async () => {
|
|
582
|
+
const response = await meeting.enableBNR();
|
|
583
|
+
|
|
584
|
+
assert.equal(response, true);
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
it('should throw error for inappropriate sample rate and send error metrics', async () => {
|
|
588
|
+
const fakeMediaTrack = () => ({
|
|
589
|
+
stop: () => {},
|
|
590
|
+
readyState: 'live',
|
|
591
|
+
getSettings: () => ({
|
|
592
|
+
sampleRate: 49000
|
|
593
|
+
})
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
sinon.stub(meeting.mediaProperties, 'audioTrack').value(fakeMediaTrack());
|
|
597
|
+
await meeting.enableBNR().catch((err) => {
|
|
598
|
+
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
599
|
+
assert.calledWith(
|
|
600
|
+
Metrics.sendBehavioralMetric,
|
|
601
|
+
BEHAVIORAL_METRICS.ENABLE_BNR_FAILURE, {
|
|
602
|
+
reason: err.message,
|
|
603
|
+
stack: err.stack
|
|
604
|
+
}
|
|
605
|
+
);
|
|
606
|
+
assert.equal(err.message, 'Sample rate of 49000 is not supported.');
|
|
607
|
+
});
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
it('should send metrics for enable bnr success', async () => {
|
|
611
|
+
const response = await meeting.enableBNR();
|
|
612
|
+
|
|
613
|
+
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
614
|
+
assert.calledWith(
|
|
615
|
+
Metrics.sendBehavioralMetric,
|
|
616
|
+
BEHAVIORAL_METRICS.ENABLE_BNR_SUCCESS,
|
|
617
|
+
);
|
|
618
|
+
assert.equal(response, true);
|
|
619
|
+
});
|
|
620
|
+
});
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
describe('#disableBNR', () => {
|
|
624
|
+
it('should have #disableBnr', () => {
|
|
625
|
+
assert.exists(meeting.disableBNR);
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
it('should return true if bnr is disabled on bnr enabled track', async () => {
|
|
629
|
+
const response = await meeting.disableBNR();
|
|
630
|
+
|
|
631
|
+
assert.equal(response, true);
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
it('should throw error if bnr is not enabled before disabling and send error metrics', async () => {
|
|
635
|
+
await meeting.disableBNR().catch((err) => {
|
|
636
|
+
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
637
|
+
assert.calledWith(
|
|
638
|
+
Metrics.sendBehavioralMetric,
|
|
639
|
+
BEHAVIORAL_METRICS.DISABLE_BNR_FAILURE,
|
|
640
|
+
);
|
|
641
|
+
assert.equal(err.message, 'Can not disable as BNR is not enabled');
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
});
|
|
645
|
+
});
|
|
448
646
|
describe('#muteVideo', () => {
|
|
449
647
|
it('should have #muteVideo', () => {
|
|
450
648
|
assert.exists(meeting.muteVideo);
|
|
@@ -2606,7 +2804,6 @@ describe('plugin-meetings', () => {
|
|
|
2606
2804
|
});
|
|
2607
2805
|
|
|
2608
2806
|
it('should send metrics on reconnect failure', async () => {
|
|
2609
|
-
sandbox.stub(Metrics, 'sendBehavioralMetric');
|
|
2610
2807
|
await assert.isRejected(meeting.reconnect());
|
|
2611
2808
|
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
2612
2809
|
assert.calledWith(
|