@webex/plugin-meetings 3.0.0 → 3.1.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/common/errors/{reconnection-in-progress.js → reconnection-not-started.js} +27 -15
- package/dist/common/errors/reconnection-not-started.js.map +1 -0
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +18 -6
- package/dist/constants.js.map +1 -1
- package/dist/index.js +86 -0
- package/dist/index.js.map +1 -1
- package/dist/interpretation/index.js +16 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +7 -1
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +10 -0
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +15 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/selfUtils.js +5 -0
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +163 -0
- package/dist/media/MediaConnectionAwaiter.js.map +1 -0
- package/dist/media/index.js +4 -1
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +106 -81
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +6 -0
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +1010 -753
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/muteState.js +37 -25
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +32 -23
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +10 -0
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/util.js +304 -267
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +334 -295
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/index.js +21 -23
- package/dist/meetings/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +1 -1
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +16 -2
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +179 -65
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +22 -0
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/reachability/clusterReachability.js +29 -15
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +18 -2
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +12 -10
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.js +19 -0
- package/dist/reachability/util.js.map +1 -1
- package/dist/reconnection-manager/index.js +140 -110
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/index.js +15 -0
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +3 -3
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +307 -126
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/statsAnalyzer/index.js +57 -30
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +3 -0
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/common/errors/reconnection-not-started.d.ts +13 -0
- package/dist/{config.d.ts → types/config.d.ts} +1 -0
- package/dist/{constants.d.ts → types/constants.d.ts} +15 -6
- package/dist/types/index.d.ts +19 -0
- package/dist/types/media/MediaConnectionAwaiter.d.ts +61 -0
- package/dist/{media → types/media}/properties.d.ts +26 -2
- package/dist/{meeting → types/meeting}/in-meeting-actions.d.ts +6 -0
- package/dist/{meeting → types/meeting}/index.d.ts +29 -12
- package/dist/{meeting → types/meeting}/muteState.d.ts +2 -8
- package/dist/{meeting → types/meeting}/request.d.ts +3 -0
- package/dist/{meeting → types/meeting}/util.d.ts +3 -0
- package/dist/{meeting-info → types/meeting-info}/index.d.ts +1 -1
- package/dist/{meeting-info → types/meeting-info}/meeting-info-v2.d.ts +1 -1
- package/dist/types/meeting-info/util.d.ts +49 -0
- package/dist/types/meeting-info/utilv2.d.ts +65 -0
- package/dist/{meetings → types/meetings}/index.d.ts +9 -16
- package/dist/{multistream → types/multistream}/mediaRequestManager.d.ts +2 -1
- package/dist/{multistream → types/multistream}/remoteMediaGroup.d.ts +2 -0
- package/dist/{multistream → types/multistream}/remoteMediaManager.d.ts +15 -0
- package/dist/{multistream → types/multistream}/sendSlotManager.d.ts +9 -1
- package/dist/{reachability → types/reachability}/clusterReachability.d.ts +1 -0
- package/dist/{reachability → types/reachability}/index.d.ts +4 -0
- package/dist/{reachability → types/reachability}/util.d.ts +7 -0
- package/dist/{reconnection-manager → types/reconnection-manager}/index.d.ts +4 -14
- package/dist/{roap → types/roap}/index.d.ts +10 -2
- package/dist/{roap → types/roap}/turnDiscovery.d.ts +64 -17
- package/dist/webinar/index.js +1 -1
- package/package.json +23 -23
- package/src/common/errors/reconnection-not-started.ts +25 -0
- package/src/config.ts +1 -0
- package/src/constants.ts +18 -6
- package/src/index.ts +31 -0
- package/src/interpretation/index.ts +18 -1
- package/src/locus-info/controlsUtils.ts +11 -0
- package/src/locus-info/index.ts +16 -0
- package/src/locus-info/mediaSharesUtils.ts +16 -0
- package/src/locus-info/selfUtils.ts +5 -0
- package/src/media/MediaConnectionAwaiter.ts +174 -0
- package/src/media/index.ts +3 -1
- package/src/media/properties.ts +73 -46
- package/src/meeting/in-meeting-actions.ts +12 -0
- package/src/meeting/index.ts +389 -180
- package/src/meeting/muteState.ts +34 -20
- package/src/meeting/request.ts +18 -2
- package/src/meeting/util.ts +9 -0
- package/src/meeting-info/util.ts +241 -233
- package/src/meeting-info/utilv2.ts +250 -243
- package/src/meetings/index.ts +20 -24
- package/src/multistream/mediaRequestManager.ts +4 -1
- package/src/multistream/remoteMediaGroup.ts +19 -0
- package/src/multistream/remoteMediaManager.ts +101 -16
- package/src/multistream/sendSlotManager.ts +28 -0
- package/src/reachability/clusterReachability.ts +20 -5
- package/src/reachability/index.ts +24 -1
- package/src/reachability/request.ts +15 -11
- package/src/reachability/util.ts +21 -0
- package/src/reconnection-manager/index.ts +129 -106
- package/src/roap/index.ts +25 -3
- package/src/roap/request.ts +3 -3
- package/src/roap/turnDiscovery.ts +244 -78
- package/src/statsAnalyzer/index.ts +67 -27
- package/src/statsAnalyzer/mqaUtil.ts +5 -0
- package/test/integration/spec/journey.js +14 -14
- package/test/integration/spec/space-meeting.js +1 -1
- package/test/unit/spec/interpretation/index.ts +39 -3
- package/test/unit/spec/locus-info/controlsUtils.js +20 -0
- package/test/unit/spec/locus-info/index.js +49 -19
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +9 -0
- package/test/unit/spec/locus-info/selfUtils.js +42 -12
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +344 -0
- package/test/unit/spec/media/index.ts +89 -78
- package/test/unit/spec/media/properties.ts +160 -209
- package/test/unit/spec/meeting/in-meeting-actions.ts +6 -0
- package/test/unit/spec/meeting/index.js +833 -205
- package/test/unit/spec/meeting/muteState.js +219 -67
- package/test/unit/spec/meeting/request.js +21 -0
- package/test/unit/spec/meeting/utils.js +9 -1
- package/test/unit/spec/meeting-info/utilv2.js +6 -0
- package/test/unit/spec/meetings/index.js +41 -26
- package/test/unit/spec/multistream/mediaRequestManager.ts +20 -2
- package/test/unit/spec/multistream/remoteMediaGroup.ts +79 -1
- package/test/unit/spec/multistream/remoteMediaManager.ts +199 -1
- package/test/unit/spec/multistream/sendSlotManager.ts +50 -18
- package/test/unit/spec/reachability/clusterReachability.ts +86 -22
- package/test/unit/spec/reachability/index.ts +197 -60
- package/test/unit/spec/reachability/request.js +15 -7
- package/test/unit/spec/reachability/util.ts +32 -2
- package/test/unit/spec/reconnection-manager/index.js +155 -39
- package/test/unit/spec/roap/index.ts +61 -6
- package/test/unit/spec/roap/turnDiscovery.ts +298 -16
- package/test/unit/spec/stats-analyzer/index.js +190 -0
- package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
- package/dist/common/errors/reconnection-in-progress.js.map +0 -1
- package/dist/index.d.ts +0 -7
- package/dist/meeting-info/util.d.ts +0 -2
- package/dist/meeting-info/utilv2.d.ts +0 -2
- package/dist/member/member.types.d.ts +0 -11
- package/dist/member/member.types.js +0 -17
- package/dist/member/member.types.js.map +0 -1
- package/src/common/errors/reconnection-in-progress.ts +0 -8
- package/src/member/member.types.ts +0 -13
- /package/dist/{annotation → types/annotation}/annotation.types.d.ts +0 -0
- /package/dist/{annotation → types/annotation}/constants.d.ts +0 -0
- /package/dist/{annotation → types/annotation}/index.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/breakout.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/collection.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/edit-lock-error.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/events.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/index.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/request.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/utils.d.ts +0 -0
- /package/dist/{common → types/common}/browser-detection.d.ts +0 -0
- /package/dist/{common → types/common}/collection.d.ts +0 -0
- /package/dist/{common → types/common}/config.d.ts +0 -0
- /package/dist/{common → types/common}/errors/captcha-error.d.ts +0 -0
- /package/dist/{common → types/common}/errors/intent-to-join.d.ts +0 -0
- /package/dist/{common → types/common}/errors/join-meeting.d.ts +0 -0
- /package/dist/{common → types/common}/errors/media.d.ts +0 -0
- /package/dist/{common → types/common}/errors/no-meeting-info.d.ts +0 -0
- /package/dist/{common → types/common}/errors/parameter.d.ts +0 -0
- /package/dist/{common → types/common}/errors/password-error.d.ts +0 -0
- /package/dist/{common → types/common}/errors/permission.d.ts +0 -0
- /package/dist/{common → types/common}/errors/reclaim-host-role-errors.d.ts +0 -0
- /package/dist/{common → types/common}/errors/reconnection.d.ts +0 -0
- /package/dist/{common → types/common}/errors/stats.d.ts +0 -0
- /package/dist/{common → types/common}/errors/webex-errors.d.ts +0 -0
- /package/dist/{common → types/common}/errors/webex-meetings-error.d.ts +0 -0
- /package/dist/{common → types/common}/events/events-scope.d.ts +0 -0
- /package/dist/{common → types/common}/events/events.d.ts +0 -0
- /package/dist/{common → types/common}/events/trigger-proxy.d.ts +0 -0
- /package/dist/{common → types/common}/events/util.d.ts +0 -0
- /package/dist/{common → types/common}/logs/logger-config.d.ts +0 -0
- /package/dist/{common → types/common}/logs/logger-proxy.d.ts +0 -0
- /package/dist/{common → types/common}/logs/request.d.ts +0 -0
- /package/dist/{common → types/common}/queue.d.ts +0 -0
- /package/dist/{controls-options-manager → types/controls-options-manager}/constants.d.ts +0 -0
- /package/dist/{controls-options-manager → types/controls-options-manager}/enums.d.ts +0 -0
- /package/dist/{controls-options-manager → types/controls-options-manager}/index.d.ts +0 -0
- /package/dist/{controls-options-manager → types/controls-options-manager}/types.d.ts +0 -0
- /package/dist/{controls-options-manager → types/controls-options-manager}/util.d.ts +0 -0
- /package/dist/{interceptors → types/interceptors}/index.d.ts +0 -0
- /package/dist/{interceptors → types/interceptors}/locusRetry.d.ts +0 -0
- /package/dist/{interpretation → types/interpretation}/collection.d.ts +0 -0
- /package/dist/{interpretation → types/interpretation}/index.d.ts +0 -0
- /package/dist/{interpretation → types/interpretation}/siLanguage.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/controlsUtils.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/embeddedAppsUtils.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/fullState.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/hostUtils.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/index.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/infoUtils.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/mediaSharesUtils.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/parser.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/selfUtils.d.ts +0 -0
- /package/dist/{media → types/media}/index.d.ts +0 -0
- /package/dist/{media → types/media}/util.d.ts +0 -0
- /package/dist/{mediaQualityMetrics → types/mediaQualityMetrics}/config.d.ts +0 -0
- /package/dist/{meeting → types/meeting}/locusMediaRequest.d.ts +0 -0
- /package/dist/{meeting → types/meeting}/request.type.d.ts +0 -0
- /package/dist/{meeting → types/meeting}/state.d.ts +0 -0
- /package/dist/{meeting → types/meeting}/voicea-meeting.d.ts +0 -0
- /package/dist/{meeting-info → types/meeting-info}/collection.d.ts +0 -0
- /package/dist/{meeting-info → types/meeting-info}/request.d.ts +0 -0
- /package/dist/{meetings → types/meetings}/collection.d.ts +0 -0
- /package/dist/{meetings → types/meetings}/meetings.types.d.ts +0 -0
- /package/dist/{meetings → types/meetings}/request.d.ts +0 -0
- /package/dist/{meetings → types/meetings}/util.d.ts +0 -0
- /package/dist/{member → types/member}/index.d.ts +0 -0
- /package/dist/{member → types/member}/types.d.ts +0 -0
- /package/dist/{member → types/member}/util.d.ts +0 -0
- /package/dist/{members → types/members}/collection.d.ts +0 -0
- /package/dist/{members → types/members}/index.d.ts +0 -0
- /package/dist/{members → types/members}/request.d.ts +0 -0
- /package/dist/{members → types/members}/types.d.ts +0 -0
- /package/dist/{members → types/members}/util.d.ts +0 -0
- /package/dist/{metrics → types/metrics}/constants.d.ts +0 -0
- /package/dist/{metrics → types/metrics}/index.d.ts +0 -0
- /package/dist/{multistream → types/multistream}/receiveSlot.d.ts +0 -0
- /package/dist/{multistream → types/multistream}/receiveSlotManager.d.ts +0 -0
- /package/dist/{multistream → types/multistream}/remoteMedia.d.ts +0 -0
- /package/dist/{networkQualityMonitor → types/networkQualityMonitor}/index.d.ts +0 -0
- /package/dist/{personal-meeting-room → types/personal-meeting-room}/index.d.ts +0 -0
- /package/dist/{personal-meeting-room → types/personal-meeting-room}/request.d.ts +0 -0
- /package/dist/{personal-meeting-room → types/personal-meeting-room}/util.d.ts +0 -0
- /package/dist/{reachability → types/reachability}/request.d.ts +0 -0
- /package/dist/{reactions → types/reactions}/constants.d.ts +0 -0
- /package/dist/{reactions → types/reactions}/reactions.d.ts +0 -0
- /package/dist/{reactions → types/reactions}/reactions.type.d.ts +0 -0
- /package/dist/{recording-controller → types/recording-controller}/enums.d.ts +0 -0
- /package/dist/{recording-controller → types/recording-controller}/index.d.ts +0 -0
- /package/dist/{recording-controller → types/recording-controller}/util.d.ts +0 -0
- /package/dist/{roap → types/roap}/request.d.ts +0 -0
- /package/dist/{rtcMetrics → types/rtcMetrics}/constants.d.ts +0 -0
- /package/dist/{rtcMetrics → types/rtcMetrics}/index.d.ts +0 -0
- /package/dist/{statsAnalyzer → types/statsAnalyzer}/global.d.ts +0 -0
- /package/dist/{statsAnalyzer → types/statsAnalyzer}/index.d.ts +0 -0
- /package/dist/{statsAnalyzer → types/statsAnalyzer}/mqaUtil.d.ts +0 -0
- /package/dist/{transcription → types/transcription}/index.d.ts +0 -0
- /package/dist/{webinar → types/webinar}/collection.d.ts +0 -0
- /package/dist/{webinar → types/webinar}/index.d.ts +0 -0
- /package/test/unit/spec/locus-info/{lib/selfConstant.js → selfConstant.js} +0 -0
package/src/meeting/index.ts
CHANGED
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
ClientEventLeaveReason,
|
|
11
11
|
CallDiagnosticUtils,
|
|
12
12
|
} from '@webex/internal-plugin-metrics';
|
|
13
|
+
import {ClientEvent as RawClientEvent} from '@webex/event-dictionary-ts';
|
|
14
|
+
|
|
13
15
|
import {
|
|
14
16
|
ConnectionState,
|
|
15
17
|
Errors,
|
|
@@ -50,8 +52,13 @@ import {
|
|
|
50
52
|
import {StatsAnalyzer, EVENTS as StatsAnalyzerEvents} from '../statsAnalyzer';
|
|
51
53
|
import NetworkQualityMonitor from '../networkQualityMonitor';
|
|
52
54
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
55
|
+
import EventsUtil from '../common/events/util';
|
|
53
56
|
import Trigger from '../common/events/trigger-proxy';
|
|
54
|
-
import Roap
|
|
57
|
+
import Roap, {
|
|
58
|
+
type TurnDiscoveryResult,
|
|
59
|
+
type TurnServerInfo,
|
|
60
|
+
type TurnDiscoverySkipReason,
|
|
61
|
+
} from '../roap/index';
|
|
55
62
|
import Media, {type BundlePolicy} from '../media';
|
|
56
63
|
import MediaProperties from '../media/properties';
|
|
57
64
|
import MeetingStateMachine from './state';
|
|
@@ -59,6 +66,7 @@ import {createMuteState} from './muteState';
|
|
|
59
66
|
import LocusInfo from '../locus-info';
|
|
60
67
|
import Metrics from '../metrics';
|
|
61
68
|
import ReconnectionManager from '../reconnection-manager';
|
|
69
|
+
import ReconnectionNotStartedError from '../common/errors/reconnection-not-started';
|
|
62
70
|
import MeetingRequest from './request';
|
|
63
71
|
import Members from '../members/index';
|
|
64
72
|
import MeetingUtil from './util';
|
|
@@ -69,8 +77,6 @@ import MediaUtil from '../media/util';
|
|
|
69
77
|
import {Reactions, SkinTones} from '../reactions/reactions';
|
|
70
78
|
import PasswordError from '../common/errors/password-error';
|
|
71
79
|
import CaptchaError from '../common/errors/captcha-error';
|
|
72
|
-
import ReconnectionError from '../common/errors/reconnection';
|
|
73
|
-
import ReconnectInProgress from '../common/errors/reconnection-in-progress';
|
|
74
80
|
import {
|
|
75
81
|
_CONVERSATION_URL_,
|
|
76
82
|
_INCOMING_,
|
|
@@ -110,6 +116,7 @@ import {
|
|
|
110
116
|
MEETING_PERMISSION_TOKEN_REFRESH_REASON,
|
|
111
117
|
ROAP_OFFER_ANSWER_EXCHANGE_TIMEOUT,
|
|
112
118
|
RECONNECTION,
|
|
119
|
+
NAMED_MEDIA_GROUP_TYPE_AUDIO,
|
|
113
120
|
LANGUAGE_ENGLISH,
|
|
114
121
|
} from '../constants';
|
|
115
122
|
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
@@ -119,7 +126,6 @@ import {
|
|
|
119
126
|
MeetingInfoV2CaptchaError,
|
|
120
127
|
MeetingInfoV2PolicyError,
|
|
121
128
|
} from '../meeting-info/meeting-info-v2';
|
|
122
|
-
import BrowserDetection from '../common/browser-detection';
|
|
123
129
|
import {CSI, ReceiveSlotManager} from '../multistream/receiveSlotManager';
|
|
124
130
|
import SendSlotManager from '../multistream/sendSlotManager';
|
|
125
131
|
import {MediaRequestManager} from '../multistream/mediaRequestManager';
|
|
@@ -147,8 +153,6 @@ import ControlsOptionsManager from '../controls-options-manager';
|
|
|
147
153
|
import PermissionError from '../common/errors/permission';
|
|
148
154
|
import {LocusMediaRequest} from './locusMediaRequest';
|
|
149
155
|
|
|
150
|
-
const {isBrowser} = BrowserDetection();
|
|
151
|
-
|
|
152
156
|
const logRequest = (request: any, {logText = ''}) => {
|
|
153
157
|
LoggerProxy.logger.info(`${logText} - sending request`);
|
|
154
158
|
|
|
@@ -614,8 +618,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
614
618
|
resourceUrl: string;
|
|
615
619
|
selfId: string;
|
|
616
620
|
state: any;
|
|
617
|
-
localAudioStreamMuteStateHandler: (
|
|
618
|
-
localVideoStreamMuteStateHandler: (
|
|
621
|
+
localAudioStreamMuteStateHandler: () => void;
|
|
622
|
+
localVideoStreamMuteStateHandler: () => void;
|
|
619
623
|
localOutputTrackChangeHandler: () => void;
|
|
620
624
|
roles: any[];
|
|
621
625
|
environment: string;
|
|
@@ -623,21 +627,23 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
623
627
|
allowMediaInLobby: boolean;
|
|
624
628
|
localShareInstanceId: string;
|
|
625
629
|
remoteShareInstanceId: string;
|
|
626
|
-
turnDiscoverySkippedReason:
|
|
630
|
+
turnDiscoverySkippedReason: TurnDiscoverySkipReason;
|
|
627
631
|
turnServerUsed: boolean;
|
|
628
632
|
areVoiceaEventsSetup = false;
|
|
633
|
+
|
|
629
634
|
voiceaListenerCallbacks: object = {
|
|
630
635
|
[VOICEAEVENTS.VOICEA_ANNOUNCEMENT]: (payload: Transcription['languageOptions']) => {
|
|
631
636
|
this.transcription.languageOptions = payload;
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
{
|
|
637
|
+
|
|
638
|
+
LoggerProxy.logger.debug(
|
|
639
|
+
`${EventsUtil.getScopeLog({
|
|
635
640
|
file: 'meeting/index',
|
|
636
641
|
function: 'setUpVoiceaListeners',
|
|
637
|
-
}
|
|
638
|
-
EVENT_TRIGGERS.MEETING_STARTED_RECEIVING_TRANSCRIPTION,
|
|
639
|
-
payload
|
|
642
|
+
})}event#${EVENT_TRIGGERS.MEETING_STARTED_RECEIVING_TRANSCRIPTION}`
|
|
640
643
|
);
|
|
644
|
+
|
|
645
|
+
// @ts-ignore
|
|
646
|
+
this.trigger(EVENT_TRIGGERS.MEETING_STARTED_RECEIVING_TRANSCRIPTION, payload);
|
|
641
647
|
},
|
|
642
648
|
[VOICEAEVENTS.CAPTIONS_TURNED_ON]: () => {
|
|
643
649
|
this.transcription.status = TURN_ON_CAPTION_STATUS.ENABLED;
|
|
@@ -650,18 +656,19 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
650
656
|
},
|
|
651
657
|
[VOICEAEVENTS.NEW_CAPTION]: (data) => {
|
|
652
658
|
processNewCaptions({data, meeting: this});
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
{
|
|
659
|
+
|
|
660
|
+
LoggerProxy.logger.debug(
|
|
661
|
+
`${EventsUtil.getScopeLog({
|
|
656
662
|
file: 'meeting/index',
|
|
657
663
|
function: 'setUpVoiceaListeners',
|
|
658
|
-
}
|
|
659
|
-
EVENT_TRIGGERS.MEETING_CAPTION_RECEIVED,
|
|
660
|
-
{
|
|
661
|
-
captions: this.transcription.captions,
|
|
662
|
-
interimCaptions: this.transcription.interimCaptions,
|
|
663
|
-
}
|
|
664
|
+
})}event#${EVENT_TRIGGERS.MEETING_CAPTION_RECEIVED}`
|
|
664
665
|
);
|
|
666
|
+
|
|
667
|
+
// @ts-ignore
|
|
668
|
+
this.trigger(EVENT_TRIGGERS.MEETING_CAPTION_RECEIVED, {
|
|
669
|
+
captions: this.transcription.captions,
|
|
670
|
+
interimCaptions: this.transcription.interimCaptions,
|
|
671
|
+
});
|
|
665
672
|
},
|
|
666
673
|
};
|
|
667
674
|
|
|
@@ -670,6 +677,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
670
677
|
private deferSDPAnswer?: Defer; // used for waiting for a response
|
|
671
678
|
private sdpResponseTimer?: ReturnType<typeof setTimeout>;
|
|
672
679
|
private hasMediaConnectionConnectedAtLeastOnce: boolean;
|
|
680
|
+
private joinWithMediaRetryInfo?: {isRetry: boolean; prevJoinResponse?: any};
|
|
673
681
|
|
|
674
682
|
/**
|
|
675
683
|
* @param {Object} attrs
|
|
@@ -1380,12 +1388,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1380
1388
|
*/
|
|
1381
1389
|
this.remoteMediaManager = null;
|
|
1382
1390
|
|
|
1383
|
-
this.localAudioStreamMuteStateHandler = (
|
|
1384
|
-
this.audio.handleLocalStreamMuteStateChange(this
|
|
1391
|
+
this.localAudioStreamMuteStateHandler = () => {
|
|
1392
|
+
this.audio.handleLocalStreamMuteStateChange(this);
|
|
1385
1393
|
};
|
|
1386
1394
|
|
|
1387
|
-
this.localVideoStreamMuteStateHandler = (
|
|
1388
|
-
this.video.handleLocalStreamMuteStateChange(this
|
|
1395
|
+
this.localVideoStreamMuteStateHandler = () => {
|
|
1396
|
+
this.video.handleLocalStreamMuteStateChange(this);
|
|
1389
1397
|
};
|
|
1390
1398
|
|
|
1391
1399
|
// The handling of output track changes should be done inside
|
|
@@ -1451,6 +1459,15 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1451
1459
|
* @memberof Meeting
|
|
1452
1460
|
*/
|
|
1453
1461
|
this.hasMediaConnectionConnectedAtLeastOnce = false;
|
|
1462
|
+
|
|
1463
|
+
/**
|
|
1464
|
+
* Information needed for a retry of a call to joinWithMedia
|
|
1465
|
+
* @instance
|
|
1466
|
+
* @type {{isRetry: boolean; prevJoinResponse?: any}}
|
|
1467
|
+
* @private
|
|
1468
|
+
* @memberof Meeting
|
|
1469
|
+
*/
|
|
1470
|
+
this.joinWithMediaRetryInfo = {isRetry: false, prevJoinResponse: undefined};
|
|
1454
1471
|
}
|
|
1455
1472
|
|
|
1456
1473
|
/**
|
|
@@ -2393,6 +2410,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2393
2410
|
}
|
|
2394
2411
|
);
|
|
2395
2412
|
|
|
2413
|
+
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_MEETING_MANUAL_CAPTION_UPDATED, ({enable}) => {
|
|
2414
|
+
Trigger.trigger(
|
|
2415
|
+
this,
|
|
2416
|
+
{
|
|
2417
|
+
file: 'meeting/index',
|
|
2418
|
+
function: 'setupLocusControlsListener',
|
|
2419
|
+
},
|
|
2420
|
+
EVENT_TRIGGERS.MEETING_MANUAL_CAPTION_UPDATED,
|
|
2421
|
+
{enable}
|
|
2422
|
+
);
|
|
2423
|
+
});
|
|
2424
|
+
|
|
2396
2425
|
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_MEETING_BREAKOUT_UPDATED, ({breakout}) => {
|
|
2397
2426
|
this.breakouts.updateBreakout(breakout);
|
|
2398
2427
|
Trigger.trigger(
|
|
@@ -2518,6 +2547,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2518
2547
|
{
|
|
2519
2548
|
annotationInfo: contentShare?.annotation,
|
|
2520
2549
|
meetingId: this.id,
|
|
2550
|
+
resourceType: contentShare?.resourceType,
|
|
2521
2551
|
}
|
|
2522
2552
|
);
|
|
2523
2553
|
}
|
|
@@ -2546,7 +2576,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2546
2576
|
contentShare.deviceUrlSharing === previousContentShare.deviceUrlSharing &&
|
|
2547
2577
|
whiteboardShare.beneficiaryId === previousWhiteboardShare?.beneficiaryId &&
|
|
2548
2578
|
whiteboardShare.disposition === previousWhiteboardShare?.disposition &&
|
|
2549
|
-
whiteboardShare.resourceUrl === previousWhiteboardShare?.resourceUrl
|
|
2579
|
+
whiteboardShare.resourceUrl === previousWhiteboardShare?.resourceUrl &&
|
|
2580
|
+
contentShare.resourceType === previousContentShare?.resourceType
|
|
2550
2581
|
) {
|
|
2551
2582
|
// nothing changed, so ignore
|
|
2552
2583
|
// (this happens when we steal presentation from remote)
|
|
@@ -2668,6 +2699,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2668
2699
|
url: contentShare.url,
|
|
2669
2700
|
shareInstanceId: this.remoteShareInstanceId,
|
|
2670
2701
|
annotationInfo: contentShare.annotation,
|
|
2702
|
+
resourceType: contentShare.resourceType,
|
|
2671
2703
|
}
|
|
2672
2704
|
);
|
|
2673
2705
|
};
|
|
@@ -2760,6 +2792,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2760
2792
|
url: contentShare.url,
|
|
2761
2793
|
shareInstanceId: this.remoteShareInstanceId,
|
|
2762
2794
|
annotationInfo: contentShare.annotation,
|
|
2795
|
+
resourceType: contentShare.resourceType,
|
|
2763
2796
|
}
|
|
2764
2797
|
);
|
|
2765
2798
|
this.members.locusMediaSharesUpdate(payload);
|
|
@@ -3069,6 +3102,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3069
3102
|
options: {meetingId: this.id},
|
|
3070
3103
|
});
|
|
3071
3104
|
}
|
|
3105
|
+
this.updateLLMConnection();
|
|
3072
3106
|
});
|
|
3073
3107
|
|
|
3074
3108
|
// @ts-ignore - check if MEDIA_INACTIVITY exists
|
|
@@ -3127,7 +3161,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3127
3161
|
});
|
|
3128
3162
|
|
|
3129
3163
|
this.locusInfo.on(LOCUSINFO.EVENTS.SELF_MEETING_INTERPRETATION_CHANGED, (payload) => {
|
|
3130
|
-
this.simultaneousInterpretation.updateSelfInterpretation(payload);
|
|
3164
|
+
const targetChanged = this.simultaneousInterpretation.updateSelfInterpretation(payload);
|
|
3131
3165
|
Trigger.trigger(
|
|
3132
3166
|
this,
|
|
3133
3167
|
{
|
|
@@ -3136,6 +3170,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3136
3170
|
},
|
|
3137
3171
|
EVENT_TRIGGERS.MEETING_INTERPRETATION_UPDATE
|
|
3138
3172
|
);
|
|
3173
|
+
if (targetChanged && this.mediaProperties.audioStream) {
|
|
3174
|
+
this.setSendNamedMediaGroup(MediaType.AudioMain);
|
|
3175
|
+
}
|
|
3139
3176
|
});
|
|
3140
3177
|
|
|
3141
3178
|
this.locusInfo.on(LOCUSINFO.EVENTS.SELF_ROLES_CHANGED, (payload) => {
|
|
@@ -3450,8 +3487,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3450
3487
|
this.owner =
|
|
3451
3488
|
locusMeetingObject?.info.owner || meetingInfo?.owner || meetingInfo?.hostId || this.owner;
|
|
3452
3489
|
this.permissionToken = meetingInfo?.permissionToken;
|
|
3453
|
-
this.
|
|
3454
|
-
|
|
3490
|
+
if (this.permissionToken) {
|
|
3491
|
+
this.setPermissionTokenPayload(meetingInfo?.permissionToken);
|
|
3492
|
+
this.setSelfUserPolicies();
|
|
3493
|
+
}
|
|
3455
3494
|
// Need to populate environment when sending CA event
|
|
3456
3495
|
this.environment = locusMeetingObject?.info.channel || meetingInfo?.channel;
|
|
3457
3496
|
}
|
|
@@ -3557,6 +3596,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3557
3596
|
canStartTranscribing: MeetingUtil.canStartTranscribing(this.userDisplayHints),
|
|
3558
3597
|
canStopTranscribing: MeetingUtil.canStopTranscribing(this.userDisplayHints),
|
|
3559
3598
|
isClosedCaptionActive: MeetingUtil.isClosedCaptionActive(this.userDisplayHints),
|
|
3599
|
+
canStartManualCaption: MeetingUtil.canStartManualCaption(this.userDisplayHints),
|
|
3600
|
+
canStopManualCaption: MeetingUtil.canStopManualCaption(this.userDisplayHints),
|
|
3601
|
+
isManualCaptionActive: MeetingUtil.isManualCaptionActive(this.userDisplayHints),
|
|
3560
3602
|
isSaveTranscriptsEnabled: MeetingUtil.isSaveTranscriptsEnabled(this.userDisplayHints),
|
|
3561
3603
|
isWebexAssistantActive: MeetingUtil.isWebexAssistantActive(this.userDisplayHints),
|
|
3562
3604
|
canViewCaptionPanel: MeetingUtil.canViewCaptionPanel(this.userDisplayHints),
|
|
@@ -3887,7 +3929,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3887
3929
|
private async setLocalAudioStream(localStream?: LocalMicrophoneStream) {
|
|
3888
3930
|
const oldStream = this.mediaProperties.audioStream;
|
|
3889
3931
|
|
|
3890
|
-
oldStream?.off(
|
|
3932
|
+
oldStream?.off(
|
|
3933
|
+
LocalStreamEventNames.UserMuteStateChange,
|
|
3934
|
+
this.localAudioStreamMuteStateHandler
|
|
3935
|
+
);
|
|
3936
|
+
oldStream?.off(
|
|
3937
|
+
LocalStreamEventNames.SystemMuteStateChange,
|
|
3938
|
+
this.localAudioStreamMuteStateHandler
|
|
3939
|
+
);
|
|
3891
3940
|
oldStream?.off(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
3892
3941
|
|
|
3893
3942
|
// we don't update this.mediaProperties.mediaDirection.sendAudio, because we always keep it as true to avoid extra SDP exchanges
|
|
@@ -3895,7 +3944,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3895
3944
|
|
|
3896
3945
|
this.audio.handleLocalStreamChange(this);
|
|
3897
3946
|
|
|
3898
|
-
localStream?.on(
|
|
3947
|
+
localStream?.on(
|
|
3948
|
+
LocalStreamEventNames.UserMuteStateChange,
|
|
3949
|
+
this.localAudioStreamMuteStateHandler
|
|
3950
|
+
);
|
|
3951
|
+
localStream?.on(
|
|
3952
|
+
LocalStreamEventNames.SystemMuteStateChange,
|
|
3953
|
+
this.localAudioStreamMuteStateHandler
|
|
3954
|
+
);
|
|
3899
3955
|
localStream?.on(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
3900
3956
|
|
|
3901
3957
|
if (!this.isMultistream || !localStream) {
|
|
@@ -3915,7 +3971,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3915
3971
|
private async setLocalVideoStream(localStream?: LocalCameraStream) {
|
|
3916
3972
|
const oldStream = this.mediaProperties.videoStream;
|
|
3917
3973
|
|
|
3918
|
-
oldStream?.off(
|
|
3974
|
+
oldStream?.off(
|
|
3975
|
+
LocalStreamEventNames.UserMuteStateChange,
|
|
3976
|
+
this.localVideoStreamMuteStateHandler
|
|
3977
|
+
);
|
|
3978
|
+
oldStream?.off(
|
|
3979
|
+
LocalStreamEventNames.SystemMuteStateChange,
|
|
3980
|
+
this.localVideoStreamMuteStateHandler
|
|
3981
|
+
);
|
|
3919
3982
|
oldStream?.off(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
3920
3983
|
|
|
3921
3984
|
// we don't update this.mediaProperties.mediaDirection.sendVideo, because we always keep it as true to avoid extra SDP exchanges
|
|
@@ -3923,7 +3986,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3923
3986
|
|
|
3924
3987
|
this.video.handleLocalStreamChange(this);
|
|
3925
3988
|
|
|
3926
|
-
localStream?.on(
|
|
3989
|
+
localStream?.on(
|
|
3990
|
+
LocalStreamEventNames.UserMuteStateChange,
|
|
3991
|
+
this.localVideoStreamMuteStateHandler
|
|
3992
|
+
);
|
|
3993
|
+
localStream?.on(
|
|
3994
|
+
LocalStreamEventNames.SystemMuteStateChange,
|
|
3995
|
+
this.localVideoStreamMuteStateHandler
|
|
3996
|
+
);
|
|
3927
3997
|
localStream?.on(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
3928
3998
|
|
|
3929
3999
|
if (!this.isMultistream || !localStream) {
|
|
@@ -3944,14 +4014,17 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3944
4014
|
private async setLocalShareVideoStream(localDisplayStream?: LocalDisplayStream) {
|
|
3945
4015
|
const oldStream = this.mediaProperties.shareVideoStream;
|
|
3946
4016
|
|
|
3947
|
-
oldStream?.off(
|
|
4017
|
+
oldStream?.off(
|
|
4018
|
+
LocalStreamEventNames.SystemMuteStateChange,
|
|
4019
|
+
this.handleShareVideoStreamMuteStateChange
|
|
4020
|
+
);
|
|
3948
4021
|
oldStream?.off(StreamEventNames.Ended, this.handleShareVideoStreamEnded);
|
|
3949
4022
|
oldStream?.off(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
3950
4023
|
|
|
3951
4024
|
this.mediaProperties.setLocalShareVideoStream(localDisplayStream);
|
|
3952
4025
|
|
|
3953
4026
|
localDisplayStream?.on(
|
|
3954
|
-
|
|
4027
|
+
LocalStreamEventNames.SystemMuteStateChange,
|
|
3955
4028
|
this.handleShareVideoStreamMuteStateChange
|
|
3956
4029
|
);
|
|
3957
4030
|
localDisplayStream?.on(StreamEventNames.Ended, this.handleShareVideoStreamEnded);
|
|
@@ -4037,10 +4110,24 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4037
4110
|
public cleanupLocalStreams() {
|
|
4038
4111
|
const {audioStream, videoStream, shareAudioStream, shareVideoStream} = this.mediaProperties;
|
|
4039
4112
|
|
|
4040
|
-
audioStream?.off(
|
|
4113
|
+
audioStream?.off(
|
|
4114
|
+
LocalStreamEventNames.UserMuteStateChange,
|
|
4115
|
+
this.localAudioStreamMuteStateHandler
|
|
4116
|
+
);
|
|
4117
|
+
audioStream?.off(
|
|
4118
|
+
LocalStreamEventNames.SystemMuteStateChange,
|
|
4119
|
+
this.localAudioStreamMuteStateHandler
|
|
4120
|
+
);
|
|
4041
4121
|
audioStream?.off(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
4042
4122
|
|
|
4043
|
-
videoStream?.off(
|
|
4123
|
+
videoStream?.off(
|
|
4124
|
+
LocalStreamEventNames.UserMuteStateChange,
|
|
4125
|
+
this.localVideoStreamMuteStateHandler
|
|
4126
|
+
);
|
|
4127
|
+
videoStream?.off(
|
|
4128
|
+
LocalStreamEventNames.SystemMuteStateChange,
|
|
4129
|
+
this.localVideoStreamMuteStateHandler
|
|
4130
|
+
);
|
|
4044
4131
|
videoStream?.off(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
4045
4132
|
|
|
4046
4133
|
shareAudioStream?.off(StreamEventNames.Ended, this.handleShareAudioStreamEnded);
|
|
@@ -4048,8 +4135,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4048
4135
|
LocalStreamEventNames.OutputTrackChange,
|
|
4049
4136
|
this.localOutputTrackChangeHandler
|
|
4050
4137
|
);
|
|
4138
|
+
|
|
4051
4139
|
shareVideoStream?.off(
|
|
4052
|
-
|
|
4140
|
+
LocalStreamEventNames.SystemMuteStateChange,
|
|
4053
4141
|
this.handleShareVideoStreamMuteStateChange
|
|
4054
4142
|
);
|
|
4055
4143
|
shareVideoStream?.off(StreamEventNames.Ended, this.handleShareVideoStreamEnded);
|
|
@@ -4441,47 +4529,112 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4441
4529
|
* }
|
|
4442
4530
|
* })
|
|
4443
4531
|
*/
|
|
4444
|
-
public joinWithMedia(
|
|
4532
|
+
public async joinWithMedia(
|
|
4445
4533
|
options: {
|
|
4446
4534
|
joinOptions?: any;
|
|
4447
4535
|
mediaOptions?: AddMediaOptions;
|
|
4448
4536
|
} = {}
|
|
4449
4537
|
) {
|
|
4450
|
-
const {mediaOptions, joinOptions} = options;
|
|
4538
|
+
const {mediaOptions, joinOptions = {}} = options;
|
|
4539
|
+
const {isRetry, prevJoinResponse} = this.joinWithMediaRetryInfo;
|
|
4451
4540
|
|
|
4452
4541
|
if (!mediaOptions?.allowMediaInLobby) {
|
|
4453
4542
|
return Promise.reject(
|
|
4454
4543
|
new ParameterError('joinWithMedia() can only be used with allowMediaInLobby set to true')
|
|
4455
4544
|
);
|
|
4456
4545
|
}
|
|
4546
|
+
this.allowMediaInLobby = true;
|
|
4457
4547
|
|
|
4458
4548
|
LoggerProxy.logger.info('Meeting:index#joinWithMedia called');
|
|
4459
4549
|
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
this.addMedia(mediaOptions).then((mediaResponse) => ({
|
|
4463
|
-
join: joinResponse,
|
|
4464
|
-
media: mediaResponse,
|
|
4465
|
-
}))
|
|
4466
|
-
)
|
|
4467
|
-
.catch((error) => {
|
|
4468
|
-
LoggerProxy.logger.error('Meeting:index#joinWithMedia --> ', error);
|
|
4550
|
+
let joined = false;
|
|
4551
|
+
let joinResponse = prevJoinResponse;
|
|
4469
4552
|
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4553
|
+
try {
|
|
4554
|
+
let turnServerInfo;
|
|
4555
|
+
let turnDiscoverySkippedReason;
|
|
4556
|
+
|
|
4557
|
+
// @ts-ignore
|
|
4558
|
+
joinOptions.reachability = await this.webex.meetings.reachability.getReachabilityResults();
|
|
4559
|
+
const turnDiscoveryRequest = await this.roap.generateTurnDiscoveryRequestMessage(this, true);
|
|
4560
|
+
|
|
4561
|
+
({turnDiscoverySkippedReason} = turnDiscoveryRequest);
|
|
4562
|
+
joinOptions.roapMessage = turnDiscoveryRequest.roapMessage;
|
|
4563
|
+
|
|
4564
|
+
if (!joinResponse) {
|
|
4565
|
+
LoggerProxy.logger.info(
|
|
4566
|
+
'Meeting:index#joinWithMedia ---> calling join with joinOptions, ',
|
|
4567
|
+
joinOptions
|
|
4481
4568
|
);
|
|
4482
4569
|
|
|
4483
|
-
|
|
4484
|
-
}
|
|
4570
|
+
joinResponse = await this.join(joinOptions);
|
|
4571
|
+
}
|
|
4572
|
+
|
|
4573
|
+
joined = true;
|
|
4574
|
+
|
|
4575
|
+
if (joinOptions.roapMessage) {
|
|
4576
|
+
({turnServerInfo, turnDiscoverySkippedReason} =
|
|
4577
|
+
await this.roap.handleTurnDiscoveryHttpResponse(this, joinResponse));
|
|
4578
|
+
|
|
4579
|
+
this.turnDiscoverySkippedReason = turnDiscoverySkippedReason;
|
|
4580
|
+
this.turnServerUsed = !!turnServerInfo;
|
|
4581
|
+
|
|
4582
|
+
if (turnServerInfo === undefined) {
|
|
4583
|
+
this.roap.abortTurnDiscovery();
|
|
4584
|
+
}
|
|
4585
|
+
}
|
|
4586
|
+
|
|
4587
|
+
const mediaResponse = await this.addMedia(mediaOptions, turnServerInfo);
|
|
4588
|
+
|
|
4589
|
+
this.joinWithMediaRetryInfo = {isRetry: false, prevJoinResponse: undefined};
|
|
4590
|
+
|
|
4591
|
+
return {
|
|
4592
|
+
join: joinResponse,
|
|
4593
|
+
media: mediaResponse,
|
|
4594
|
+
};
|
|
4595
|
+
} catch (error) {
|
|
4596
|
+
LoggerProxy.logger.error('Meeting:index#joinWithMedia --> ', error);
|
|
4597
|
+
|
|
4598
|
+
let leaveError;
|
|
4599
|
+
|
|
4600
|
+
this.roap.abortTurnDiscovery();
|
|
4601
|
+
|
|
4602
|
+
if (joined && isRetry) {
|
|
4603
|
+
try {
|
|
4604
|
+
await this.leave({resourceId: joinOptions?.resourceId, reason: 'joinWithMedia failure'});
|
|
4605
|
+
} catch (e) {
|
|
4606
|
+
LoggerProxy.logger.error('Meeting:index#joinWithMedia --> leave error', e);
|
|
4607
|
+
leaveError = e;
|
|
4608
|
+
}
|
|
4609
|
+
}
|
|
4610
|
+
|
|
4611
|
+
Metrics.sendBehavioralMetric(
|
|
4612
|
+
BEHAVIORAL_METRICS.JOIN_WITH_MEDIA_FAILURE,
|
|
4613
|
+
{
|
|
4614
|
+
correlation_id: this.correlationId,
|
|
4615
|
+
locus_id: this.locusUrl?.split('/').pop(), // if join fails, we may end up with no locusUrl
|
|
4616
|
+
reason: error.message,
|
|
4617
|
+
stack: error.stack,
|
|
4618
|
+
leaveErrorReason: leaveError?.message,
|
|
4619
|
+
isRetry,
|
|
4620
|
+
},
|
|
4621
|
+
{
|
|
4622
|
+
type: error.name,
|
|
4623
|
+
}
|
|
4624
|
+
);
|
|
4625
|
+
|
|
4626
|
+
if (!isRetry) {
|
|
4627
|
+
LoggerProxy.logger.warn('Meeting:index#joinWithMedia --> retrying call to joinWithMedia');
|
|
4628
|
+
this.joinWithMediaRetryInfo.isRetry = true;
|
|
4629
|
+
this.joinWithMediaRetryInfo.prevJoinResponse = joinResponse;
|
|
4630
|
+
|
|
4631
|
+
return this.joinWithMedia(options);
|
|
4632
|
+
}
|
|
4633
|
+
|
|
4634
|
+
this.joinWithMediaRetryInfo = {isRetry: false, prevJoinResponse: undefined};
|
|
4635
|
+
|
|
4636
|
+
throw error;
|
|
4637
|
+
}
|
|
4485
4638
|
}
|
|
4486
4639
|
|
|
4487
4640
|
/**
|
|
@@ -4510,90 +4663,28 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4510
4663
|
);
|
|
4511
4664
|
}
|
|
4512
4665
|
|
|
4513
|
-
try {
|
|
4514
|
-
LoggerProxy.logger.info('Meeting:index#reconnect --> Validating reconnect ability.');
|
|
4515
|
-
// @ts-ignore
|
|
4516
|
-
this.reconnectionManager.validate();
|
|
4517
|
-
} catch (error) {
|
|
4518
|
-
// Unable to reconnect this call
|
|
4519
|
-
if (error instanceof ReconnectInProgress) {
|
|
4520
|
-
LoggerProxy.logger.info(
|
|
4521
|
-
'Meeting:index#reconnect --> Unable to reconnect, reconnection in progress.'
|
|
4522
|
-
);
|
|
4523
|
-
} else {
|
|
4524
|
-
LoggerProxy.logger.log('Meeting:index#reconnect --> Unable to reconnect.', error);
|
|
4525
|
-
}
|
|
4526
|
-
|
|
4527
|
-
return Promise.resolve();
|
|
4528
|
-
}
|
|
4529
|
-
|
|
4530
|
-
Trigger.trigger(
|
|
4531
|
-
this,
|
|
4532
|
-
{
|
|
4533
|
-
file: 'meeting/index',
|
|
4534
|
-
function: 'reconnect',
|
|
4535
|
-
},
|
|
4536
|
-
EVENT_TRIGGERS.MEETING_RECONNECTION_STARTING
|
|
4537
|
-
);
|
|
4538
|
-
|
|
4539
4666
|
return this.reconnectionManager
|
|
4540
|
-
.reconnect(options)
|
|
4541
|
-
|
|
4542
|
-
|
|
4667
|
+
.reconnect(options, async () => {
|
|
4668
|
+
await this.waitForRemoteSDPAnswer();
|
|
4669
|
+
await this.waitForMediaConnectionConnected();
|
|
4670
|
+
})
|
|
4543
4671
|
.then(() => {
|
|
4544
|
-
Trigger.trigger(
|
|
4545
|
-
this,
|
|
4546
|
-
{
|
|
4547
|
-
file: 'meeting/index',
|
|
4548
|
-
function: 'reconnect',
|
|
4549
|
-
},
|
|
4550
|
-
EVENT_TRIGGERS.MEETING_RECONNECTION_SUCCESS
|
|
4551
|
-
);
|
|
4552
4672
|
LoggerProxy.logger.log('Meeting:index#reconnect --> Meeting reconnect success');
|
|
4553
|
-
|
|
4554
|
-
// @ts-ignore
|
|
4555
|
-
this.webex.internal.newMetrics.submitClientEvent({
|
|
4556
|
-
name: 'client.media.recovered',
|
|
4557
|
-
payload: {
|
|
4558
|
-
recoveredBy: 'new',
|
|
4559
|
-
},
|
|
4560
|
-
options: {
|
|
4561
|
-
meetingId: this.id,
|
|
4562
|
-
},
|
|
4563
|
-
});
|
|
4564
|
-
this.reconnectionManager.setStatus(RECONNECTION.STATE.COMPLETE);
|
|
4565
4673
|
})
|
|
4566
4674
|
.catch((error) => {
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
{
|
|
4570
|
-
file: 'meeting/index',
|
|
4571
|
-
function: 'reconnect',
|
|
4572
|
-
},
|
|
4573
|
-
EVENT_TRIGGERS.MEETING_RECONNECTION_FAILURE,
|
|
4574
|
-
{
|
|
4575
|
-
error: new ReconnectionError('Reconnection failure event', error),
|
|
4576
|
-
}
|
|
4577
|
-
);
|
|
4675
|
+
if (error instanceof ReconnectionNotStartedError) {
|
|
4676
|
+
LoggerProxy.logger.log('Meeting:index#reconnect --> Meeting reconnect not started');
|
|
4578
4677
|
|
|
4678
|
+
return Promise.resolve();
|
|
4679
|
+
}
|
|
4579
4680
|
LoggerProxy.logger.error('Meeting:index#reconnect --> Meeting reconnect failed', error);
|
|
4580
4681
|
|
|
4581
|
-
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETING_RECONNECT_FAILURE, {
|
|
4582
|
-
correlation_id: this.correlationId,
|
|
4583
|
-
locus_id: this.locusUrl.split('/').pop(),
|
|
4584
|
-
reason: error.message,
|
|
4585
|
-
stack: error.stack,
|
|
4586
|
-
});
|
|
4587
|
-
|
|
4588
4682
|
this.uploadLogs({
|
|
4589
4683
|
file: 'meeting/index',
|
|
4590
4684
|
function: 'reconnect',
|
|
4591
4685
|
});
|
|
4592
4686
|
|
|
4593
|
-
return Promise.reject(
|
|
4594
|
-
})
|
|
4595
|
-
.finally(() => {
|
|
4596
|
-
this.reconnectionManager.reset();
|
|
4687
|
+
return Promise.reject(error);
|
|
4597
4688
|
});
|
|
4598
4689
|
}
|
|
4599
4690
|
|
|
@@ -4747,7 +4838,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4747
4838
|
|
|
4748
4839
|
if (this.getCurUserType() === 'host') {
|
|
4749
4840
|
// @ts-ignore
|
|
4750
|
-
await this.webex.internal.voicea.
|
|
4841
|
+
await this.webex.internal.voicea.turnOnCaptions(options?.spokenLanguage);
|
|
4751
4842
|
}
|
|
4752
4843
|
} catch (error) {
|
|
4753
4844
|
LoggerProxy.logger.error(`Meeting:index#startTranscription --> ${error}`);
|
|
@@ -5604,7 +5695,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5604
5695
|
logText: `${LOG_HEADER} Roap Offer`,
|
|
5605
5696
|
}
|
|
5606
5697
|
).catch(() => {
|
|
5607
|
-
this.deferSDPAnswer.reject();
|
|
5698
|
+
this.deferSDPAnswer.reject(new Error('failed to send ROAP SDP offer'));
|
|
5608
5699
|
clearTimeout(this.sdpResponseTimer);
|
|
5609
5700
|
this.sdpResponseTimer = undefined;
|
|
5610
5701
|
});
|
|
@@ -5951,6 +6042,20 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5951
6042
|
meetingId: this.id,
|
|
5952
6043
|
},
|
|
5953
6044
|
});
|
|
6045
|
+
|
|
6046
|
+
if (data.type === 'share') {
|
|
6047
|
+
// @ts-ignore
|
|
6048
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
6049
|
+
name: 'client.media.render.start',
|
|
6050
|
+
payload: {
|
|
6051
|
+
mediaType: 'share',
|
|
6052
|
+
shareInstanceId: this.remoteShareInstanceId,
|
|
6053
|
+
},
|
|
6054
|
+
options: {
|
|
6055
|
+
meetingId: this.id,
|
|
6056
|
+
},
|
|
6057
|
+
});
|
|
6058
|
+
}
|
|
5954
6059
|
});
|
|
5955
6060
|
this.statsAnalyzer.on(StatsAnalyzerEvents.REMOTE_MEDIA_STOPPED, (data) => {
|
|
5956
6061
|
// @ts-ignore
|
|
@@ -5964,6 +6069,20 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5964
6069
|
meetingId: this.id,
|
|
5965
6070
|
},
|
|
5966
6071
|
});
|
|
6072
|
+
|
|
6073
|
+
if (data.type === 'share') {
|
|
6074
|
+
// @ts-ignore
|
|
6075
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
6076
|
+
name: 'client.media.render.stop',
|
|
6077
|
+
payload: {
|
|
6078
|
+
mediaType: 'share',
|
|
6079
|
+
shareInstanceId: this.remoteShareInstanceId,
|
|
6080
|
+
},
|
|
6081
|
+
options: {
|
|
6082
|
+
meetingId: this.id,
|
|
6083
|
+
},
|
|
6084
|
+
});
|
|
6085
|
+
}
|
|
5967
6086
|
});
|
|
5968
6087
|
};
|
|
5969
6088
|
|
|
@@ -6020,6 +6139,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6020
6139
|
|
|
6021
6140
|
// publish the streams
|
|
6022
6141
|
if (this.mediaProperties.audioStream) {
|
|
6142
|
+
this.setSendNamedMediaGroup(MediaType.AudioMain);
|
|
6023
6143
|
await this.publishStream(MediaType.AudioMain, this.mediaProperties.audioStream);
|
|
6024
6144
|
}
|
|
6025
6145
|
if (this.mediaProperties.videoStream) {
|
|
@@ -6069,16 +6189,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6069
6189
|
private async setUpLocalStreamReferences(localStreams: LocalStreams) {
|
|
6070
6190
|
const setUpStreamPromises = [];
|
|
6071
6191
|
|
|
6072
|
-
if (localStreams?.microphone) {
|
|
6192
|
+
if (localStreams?.microphone && localStreams?.microphone?.readyState !== 'ended') {
|
|
6073
6193
|
setUpStreamPromises.push(this.setLocalAudioStream(localStreams.microphone));
|
|
6074
6194
|
}
|
|
6075
|
-
if (localStreams?.camera) {
|
|
6195
|
+
if (localStreams?.camera && localStreams?.camera?.readyState !== 'ended') {
|
|
6076
6196
|
setUpStreamPromises.push(this.setLocalVideoStream(localStreams.camera));
|
|
6077
6197
|
}
|
|
6078
|
-
if (
|
|
6198
|
+
if (
|
|
6199
|
+
localStreams?.screenShare?.video &&
|
|
6200
|
+
localStreams?.screenShare?.video?.readyState !== 'ended'
|
|
6201
|
+
) {
|
|
6079
6202
|
setUpStreamPromises.push(this.setLocalShareVideoStream(localStreams.screenShare.video));
|
|
6080
6203
|
}
|
|
6081
|
-
if (
|
|
6204
|
+
if (
|
|
6205
|
+
localStreams?.screenShare?.audio &&
|
|
6206
|
+
localStreams?.screenShare?.audio?.readyState !== 'ended'
|
|
6207
|
+
) {
|
|
6082
6208
|
setUpStreamPromises.push(this.setLocalShareAudioStream(localStreams.screenShare.audio));
|
|
6083
6209
|
}
|
|
6084
6210
|
|
|
@@ -6323,6 +6449,44 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6323
6449
|
}
|
|
6324
6450
|
}
|
|
6325
6451
|
|
|
6452
|
+
/**
|
|
6453
|
+
* Performs TURN discovery as a separate call to the Locus /media API
|
|
6454
|
+
*
|
|
6455
|
+
* @param {boolean} isRetry
|
|
6456
|
+
* @param {boolean} isForced
|
|
6457
|
+
* @returns {Promise}
|
|
6458
|
+
*/
|
|
6459
|
+
private async doTurnDiscovery(isRetry: boolean, isForced: boolean): Promise<TurnDiscoveryResult> {
|
|
6460
|
+
// @ts-ignore
|
|
6461
|
+
const cdl = this.webex.internal.newMetrics.callDiagnosticLatencies;
|
|
6462
|
+
|
|
6463
|
+
// @ts-ignore
|
|
6464
|
+
this.webex.internal.newMetrics.submitInternalEvent({
|
|
6465
|
+
name: 'internal.client.add-media.turn-discovery.start',
|
|
6466
|
+
});
|
|
6467
|
+
|
|
6468
|
+
const turnDiscoveryResult = await this.roap.doTurnDiscovery(this, isRetry, isForced);
|
|
6469
|
+
|
|
6470
|
+
this.turnDiscoverySkippedReason = turnDiscoveryResult?.turnDiscoverySkippedReason;
|
|
6471
|
+
this.turnServerUsed = !this.turnDiscoverySkippedReason;
|
|
6472
|
+
|
|
6473
|
+
// @ts-ignore
|
|
6474
|
+
this.webex.internal.newMetrics.submitInternalEvent({
|
|
6475
|
+
name: 'internal.client.add-media.turn-discovery.end',
|
|
6476
|
+
});
|
|
6477
|
+
|
|
6478
|
+
if (this.turnServerUsed && turnDiscoveryResult.turnServerInfo) {
|
|
6479
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.TURN_DISCOVERY_LATENCY, {
|
|
6480
|
+
correlation_id: this.correlationId,
|
|
6481
|
+
latency: cdl.getTurnDiscoveryTime(),
|
|
6482
|
+
turnServerUsed: this.turnServerUsed,
|
|
6483
|
+
retriedWithTurnServer: this.retriedWithTurnServer,
|
|
6484
|
+
});
|
|
6485
|
+
}
|
|
6486
|
+
|
|
6487
|
+
return turnDiscoveryResult;
|
|
6488
|
+
}
|
|
6489
|
+
|
|
6326
6490
|
/**
|
|
6327
6491
|
* Does TURN discovery, SDP offer/answer exhange, establishes ICE connection and DTLS handshake.
|
|
6328
6492
|
*
|
|
@@ -6330,43 +6494,21 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6330
6494
|
* @param {RemoteMediaManagerConfiguration} [remoteMediaManagerConfig]
|
|
6331
6495
|
* @param {BundlePolicy} [bundlePolicy]
|
|
6332
6496
|
* @param {boolean} [isForced] - let isForced be true to do turn discovery regardless of reachability results
|
|
6497
|
+
* @param {TurnServerInfo} [turnServerInfo]
|
|
6333
6498
|
* @returns {Promise<void>}
|
|
6334
6499
|
*/
|
|
6335
6500
|
private async establishMediaConnection(
|
|
6336
6501
|
remoteMediaManagerConfig?: RemoteMediaManagerConfiguration,
|
|
6337
6502
|
bundlePolicy?: BundlePolicy,
|
|
6338
|
-
isForced?: boolean
|
|
6503
|
+
isForced?: boolean,
|
|
6504
|
+
turnServerInfo?: TurnServerInfo
|
|
6339
6505
|
): Promise<void> {
|
|
6340
6506
|
const LOG_HEADER = 'Meeting:index#addMedia():establishMediaConnection -->';
|
|
6341
|
-
// @ts-ignore
|
|
6342
|
-
const cdl = this.webex.internal.newMetrics.callDiagnosticLatencies;
|
|
6343
6507
|
const isRetry = this.retriedWithTurnServer;
|
|
6344
6508
|
|
|
6345
6509
|
try {
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
name: 'internal.client.add-media.turn-discovery.start',
|
|
6349
|
-
});
|
|
6350
|
-
|
|
6351
|
-
const turnDiscoveryObject = await this.roap.doTurnDiscovery(this, isRetry, isForced);
|
|
6352
|
-
|
|
6353
|
-
this.turnDiscoverySkippedReason = turnDiscoveryObject?.turnDiscoverySkippedReason;
|
|
6354
|
-
this.turnServerUsed = !this.turnDiscoverySkippedReason;
|
|
6355
|
-
|
|
6356
|
-
// @ts-ignore
|
|
6357
|
-
this.webex.internal.newMetrics.submitInternalEvent({
|
|
6358
|
-
name: 'internal.client.add-media.turn-discovery.end',
|
|
6359
|
-
});
|
|
6360
|
-
|
|
6361
|
-
const {turnServerInfo} = turnDiscoveryObject;
|
|
6362
|
-
|
|
6363
|
-
if (this.turnServerUsed && turnServerInfo) {
|
|
6364
|
-
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.TURN_DISCOVERY_LATENCY, {
|
|
6365
|
-
correlation_id: this.correlationId,
|
|
6366
|
-
latency: cdl.getTurnDiscoveryTime(),
|
|
6367
|
-
turnServerUsed: this.turnServerUsed,
|
|
6368
|
-
retriedWithTurnServer: this.retriedWithTurnServer,
|
|
6369
|
-
});
|
|
6510
|
+
if (!turnServerInfo) {
|
|
6511
|
+
({turnServerInfo} = await this.doTurnDiscovery(isRetry, isForced));
|
|
6370
6512
|
}
|
|
6371
6513
|
|
|
6372
6514
|
const mc = await this.createMediaConnection(turnServerInfo, bundlePolicy);
|
|
@@ -6385,6 +6527,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6385
6527
|
RemoteMediaManagerEvent.AudioCreated,
|
|
6386
6528
|
EVENT_TRIGGERS.REMOTE_MEDIA_AUDIO_CREATED
|
|
6387
6529
|
);
|
|
6530
|
+
this.forwardEvent(
|
|
6531
|
+
this.remoteMediaManager,
|
|
6532
|
+
RemoteMediaManagerEvent.InterpretationAudioCreated,
|
|
6533
|
+
EVENT_TRIGGERS.REMOTE_MEDIA_INTERPRETATION_AUDIO_CREATED
|
|
6534
|
+
);
|
|
6388
6535
|
this.forwardEvent(
|
|
6389
6536
|
this.remoteMediaManager,
|
|
6390
6537
|
RemoteMediaManagerEvent.ScreenShareAudioCreated,
|
|
@@ -6478,15 +6625,21 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6478
6625
|
* Creates a media connection to the server. Media connection is required for sending or receiving any audio/video.
|
|
6479
6626
|
*
|
|
6480
6627
|
* @param {AddMediaOptions} options
|
|
6628
|
+
* @param {TurnServerInfo} turnServerInfo - TURN server information (used only internally by the SDK)
|
|
6481
6629
|
* @returns {Promise<void>}
|
|
6482
6630
|
* @public
|
|
6483
6631
|
* @memberof Meeting
|
|
6484
6632
|
*/
|
|
6485
|
-
async addMedia(
|
|
6633
|
+
async addMedia(
|
|
6634
|
+
options: AddMediaOptions = {},
|
|
6635
|
+
turnServerInfo: TurnServerInfo = undefined
|
|
6636
|
+
): Promise<void> {
|
|
6486
6637
|
this.retriedWithTurnServer = false;
|
|
6487
6638
|
this.hasMediaConnectionConnectedAtLeastOnce = false;
|
|
6488
6639
|
const LOG_HEADER = 'Meeting:index#addMedia -->';
|
|
6489
|
-
LoggerProxy.logger.info(
|
|
6640
|
+
LoggerProxy.logger.info(
|
|
6641
|
+
`${LOG_HEADER} called with: ${JSON.stringify(options)}, ${JSON.stringify(turnServerInfo)}`
|
|
6642
|
+
);
|
|
6490
6643
|
|
|
6491
6644
|
if (options.allowMediaInLobby !== true && this.meetingState !== FULL_STATE.ACTIVE) {
|
|
6492
6645
|
throw new MeetingNotActiveError();
|
|
@@ -6504,14 +6657,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6504
6657
|
shareVideoEnabled = true,
|
|
6505
6658
|
remoteMediaManagerConfig,
|
|
6506
6659
|
bundlePolicy,
|
|
6507
|
-
allowMediaInLobby,
|
|
6508
6660
|
} = options;
|
|
6509
6661
|
|
|
6510
6662
|
this.allowMediaInLobby = options?.allowMediaInLobby;
|
|
6511
6663
|
|
|
6512
6664
|
// If the user is unjoined or guest waiting in lobby dont allow the user to addMedia
|
|
6513
6665
|
// @ts-ignore - isUserUnadmitted coming from SelfUtil
|
|
6514
|
-
if (this.isUserUnadmitted && !this.wirelessShare && !allowMediaInLobby) {
|
|
6666
|
+
if (this.isUserUnadmitted && !this.wirelessShare && !this.allowMediaInLobby) {
|
|
6515
6667
|
throw new UserInLobbyError();
|
|
6516
6668
|
}
|
|
6517
6669
|
|
|
@@ -6580,15 +6732,25 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6580
6732
|
|
|
6581
6733
|
this.createStatsAnalyzer();
|
|
6582
6734
|
|
|
6583
|
-
await this.establishMediaConnection(
|
|
6735
|
+
await this.establishMediaConnection(
|
|
6736
|
+
remoteMediaManagerConfig,
|
|
6737
|
+
bundlePolicy,
|
|
6738
|
+
false,
|
|
6739
|
+
turnServerInfo
|
|
6740
|
+
);
|
|
6584
6741
|
|
|
6585
|
-
|
|
6742
|
+
if (audioEnabled || videoEnabled) {
|
|
6743
|
+
await Meeting.handleDeviceLogging();
|
|
6744
|
+
} else {
|
|
6745
|
+
LoggerProxy.logger.info(`${LOG_HEADER} device logging not required`);
|
|
6746
|
+
}
|
|
6586
6747
|
|
|
6587
6748
|
if (this.mediaProperties.hasLocalShareStream()) {
|
|
6588
6749
|
await this.enqueueScreenShareFloorRequest();
|
|
6589
6750
|
}
|
|
6590
6751
|
|
|
6591
|
-
const connectionType
|
|
6752
|
+
const {connectionType, selectedCandidatePairChanges, numTransports} =
|
|
6753
|
+
await this.mediaProperties.getCurrentConnectionInfo();
|
|
6592
6754
|
// @ts-ignore
|
|
6593
6755
|
const reachabilityStats = await this.webex.meetings.reachability.getReachabilityMetrics();
|
|
6594
6756
|
|
|
@@ -6596,8 +6758,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6596
6758
|
correlation_id: this.correlationId,
|
|
6597
6759
|
locus_id: this.locusUrl.split('/').pop(),
|
|
6598
6760
|
connectionType,
|
|
6761
|
+
selectedCandidatePairChanges,
|
|
6762
|
+
numTransports,
|
|
6599
6763
|
isMultistream: this.isMultistream,
|
|
6600
6764
|
retriedWithTurnServer: this.retriedWithTurnServer,
|
|
6765
|
+
isJoinWithMediaRetry: this.joinWithMediaRetryInfo.isRetry,
|
|
6601
6766
|
...reachabilityStats,
|
|
6602
6767
|
});
|
|
6603
6768
|
// @ts-ignore
|
|
@@ -6619,16 +6784,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6619
6784
|
// @ts-ignore
|
|
6620
6785
|
const reachabilityMetrics = await this.webex.meetings.reachability.getReachabilityMetrics();
|
|
6621
6786
|
|
|
6787
|
+
const {selectedCandidatePairChanges, numTransports} =
|
|
6788
|
+
await this.mediaProperties.getCurrentConnectionInfo();
|
|
6789
|
+
|
|
6622
6790
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_MEDIA_FAILURE, {
|
|
6623
6791
|
correlation_id: this.correlationId,
|
|
6624
6792
|
locus_id: this.locusUrl.split('/').pop(),
|
|
6625
6793
|
reason: error.message,
|
|
6626
6794
|
stack: error.stack,
|
|
6627
6795
|
code: error.code,
|
|
6796
|
+
selectedCandidatePairChanges,
|
|
6797
|
+
numTransports,
|
|
6628
6798
|
turnDiscoverySkippedReason: this.turnDiscoverySkippedReason,
|
|
6629
6799
|
turnServerUsed: this.turnServerUsed,
|
|
6630
6800
|
retriedWithTurnServer: this.retriedWithTurnServer,
|
|
6631
6801
|
isMultistream: this.isMultistream,
|
|
6802
|
+
isJoinWithMediaRetry: this.joinWithMediaRetryInfo.isRetry,
|
|
6632
6803
|
signalingState:
|
|
6633
6804
|
this.mediaProperties.webrtcMediaConnection?.multistreamConnection?.pc?.pc
|
|
6634
6805
|
?.signalingState ||
|
|
@@ -7774,9 +7945,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7774
7945
|
|
|
7775
7946
|
/**
|
|
7776
7947
|
*
|
|
7777
|
-
* @returns {string} one of 'attendee','host','cohost', returns the user type of the current user
|
|
7948
|
+
* @returns {string} one of 'panelist', 'attendee', 'host', 'cohost', returns the user type of the current user
|
|
7778
7949
|
*/
|
|
7779
|
-
getCurUserType() {
|
|
7950
|
+
getCurUserType(): RawClientEvent['userType'] | null {
|
|
7780
7951
|
const {roles} = this;
|
|
7781
7952
|
if (roles) {
|
|
7782
7953
|
if (roles.includes(SELF_ROLES.MODERATOR)) {
|
|
@@ -7785,8 +7956,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7785
7956
|
if (roles.includes(SELF_ROLES.COHOST)) {
|
|
7786
7957
|
return 'cohost';
|
|
7787
7958
|
}
|
|
7788
|
-
if (roles.includes(SELF_ROLES.
|
|
7789
|
-
return '
|
|
7959
|
+
if (roles.includes(SELF_ROLES.PANELIST)) {
|
|
7960
|
+
return 'panelist';
|
|
7790
7961
|
}
|
|
7791
7962
|
if (roles.includes(SELF_ROLES.ATTENDEE)) {
|
|
7792
7963
|
return 'attendee';
|
|
@@ -8096,6 +8267,33 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8096
8267
|
});
|
|
8097
8268
|
}
|
|
8098
8269
|
|
|
8270
|
+
/**
|
|
8271
|
+
* set sending named media group which the audio should send to
|
|
8272
|
+
* @param {MediaType} mediaType of the stream
|
|
8273
|
+
* @param {number} languageCode of the stream
|
|
8274
|
+
* @returns {void}
|
|
8275
|
+
*/
|
|
8276
|
+
public setSendNamedMediaGroup(mediaType: MediaType, languageCode = 0): void {
|
|
8277
|
+
if (mediaType !== MediaType.AudioMain) {
|
|
8278
|
+
throw new Error(`cannot set send named media group which media type is ${mediaType}`);
|
|
8279
|
+
}
|
|
8280
|
+
|
|
8281
|
+
const value = languageCode || this.simultaneousInterpretation.getTargetLanguageCode();
|
|
8282
|
+
let groups = [];
|
|
8283
|
+
|
|
8284
|
+
if (value) {
|
|
8285
|
+
groups = [
|
|
8286
|
+
{
|
|
8287
|
+
type: NAMED_MEDIA_GROUP_TYPE_AUDIO,
|
|
8288
|
+
value,
|
|
8289
|
+
},
|
|
8290
|
+
];
|
|
8291
|
+
}
|
|
8292
|
+
if (this.isMultistream && this.mediaProperties.webrtcMediaConnection) {
|
|
8293
|
+
this.sendSlotManager.setNamedMediaGroups(mediaType, groups);
|
|
8294
|
+
}
|
|
8295
|
+
}
|
|
8296
|
+
|
|
8099
8297
|
/**
|
|
8100
8298
|
* Publishes a stream.
|
|
8101
8299
|
*
|
|
@@ -8164,6 +8362,17 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8164
8362
|
return;
|
|
8165
8363
|
}
|
|
8166
8364
|
|
|
8365
|
+
if (
|
|
8366
|
+
streams?.microphone?.readyState === 'ended' ||
|
|
8367
|
+
streams?.camera?.readyState === 'ended' ||
|
|
8368
|
+
streams?.screenShare?.audio?.readyState === 'ended' ||
|
|
8369
|
+
streams?.screenShare?.video?.readyState === 'ended'
|
|
8370
|
+
) {
|
|
8371
|
+
throw new Error(
|
|
8372
|
+
`Attempted to publish stream with ended readyState, correlationId=${this.correlationId}`
|
|
8373
|
+
);
|
|
8374
|
+
}
|
|
8375
|
+
|
|
8167
8376
|
let floorRequestNeeded = false;
|
|
8168
8377
|
|
|
8169
8378
|
// Screenshare Audio is supported only in multi stream. So we check for screenshare audio presence only if it's a multi stream meeting
|