@webex/plugin-meetings 3.3.1-next.39 → 3.3.1-next.40
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/constants.js +2 -5
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/media/MediaConnectionAwaiter.js +6 -6
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/meeting/connectionStateHandler.js +2 -2
- package/dist/meeting/connectionStateHandler.js.map +1 -1
- package/dist/meeting/index.js +99 -104
- package/dist/meeting/index.js.map +1 -1
- package/dist/types/constants.d.ts +0 -3
- package/dist/types/meeting/index.d.ts +1 -2
- package/dist/webinar/index.js +1 -1
- package/package.json +5 -5
- package/src/constants.ts +0 -17
- package/src/media/MediaConnectionAwaiter.ts +7 -7
- package/src/meeting/connectionStateHandler.ts +3 -3
- package/src/meeting/index.ts +278 -252
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +29 -29
- package/test/unit/spec/media/index.ts +8 -9
- package/test/unit/spec/meeting/connectionStateHandler.ts +7 -7
- package/test/unit/spec/meeting/index.js +74 -78
- package/test/unit/spec/multistream/mediaRequestManager.ts +2 -2
- package/test/unit/spec/rtcMetrics/index.ts +1 -0
- package/dist/mediaQualityMetrics/config.js +0 -331
- package/dist/mediaQualityMetrics/config.js.map +0 -1
- package/dist/statsAnalyzer/global.js +0 -44
- package/dist/statsAnalyzer/global.js.map +0 -1
- package/dist/statsAnalyzer/index.js +0 -1126
- package/dist/statsAnalyzer/index.js.map +0 -1
- package/dist/statsAnalyzer/mqaUtil.js +0 -394
- package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
- package/dist/types/mediaQualityMetrics/config.d.ts +0 -258
- package/dist/types/statsAnalyzer/global.d.ts +0 -36
- package/dist/types/statsAnalyzer/index.d.ts +0 -226
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -61
- package/src/mediaQualityMetrics/config.ts +0 -266
- package/src/statsAnalyzer/global.ts +0 -37
- package/src/statsAnalyzer/index.ts +0 -1379
- package/src/statsAnalyzer/mqaUtil.ts +0 -511
- package/test/unit/spec/stats-analyzer/index.js +0 -2147
package/src/meeting/index.ts
CHANGED
|
@@ -17,11 +17,13 @@ import {
|
|
|
17
17
|
ConnectionState,
|
|
18
18
|
Errors,
|
|
19
19
|
ErrorType,
|
|
20
|
-
|
|
20
|
+
MediaConnectionEventNames,
|
|
21
21
|
MediaContent,
|
|
22
22
|
MediaType,
|
|
23
23
|
RemoteTrackType,
|
|
24
24
|
RoapMessage,
|
|
25
|
+
StatsAnalyzer,
|
|
26
|
+
StatsAnalyzerEventNames,
|
|
25
27
|
} from '@webex/internal-media-core';
|
|
26
28
|
|
|
27
29
|
import {
|
|
@@ -41,6 +43,7 @@ import {
|
|
|
41
43
|
TURN_ON_CAPTION_STATUS,
|
|
42
44
|
type MeetingTranscriptPayload,
|
|
43
45
|
} from '@webex/internal-plugin-voicea';
|
|
46
|
+
|
|
44
47
|
import {processNewCaptions} from './voicea-meeting';
|
|
45
48
|
|
|
46
49
|
import {
|
|
@@ -51,7 +54,6 @@ import {
|
|
|
51
54
|
AddMediaFailed,
|
|
52
55
|
} from '../common/errors/webex-errors';
|
|
53
56
|
|
|
54
|
-
import {StatsAnalyzer, EVENTS as StatsAnalyzerEvents} from '../statsAnalyzer';
|
|
55
57
|
import NetworkQualityMonitor from '../networkQualityMonitor';
|
|
56
58
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
57
59
|
import EventsUtil from '../common/events/util';
|
|
@@ -116,9 +118,7 @@ import {
|
|
|
116
118
|
MEETING_PERMISSION_TOKEN_REFRESH_THRESHOLD_IN_SEC,
|
|
117
119
|
MEETING_PERMISSION_TOKEN_REFRESH_REASON,
|
|
118
120
|
ROAP_OFFER_ANSWER_EXCHANGE_TIMEOUT,
|
|
119
|
-
RECONNECTION,
|
|
120
121
|
NAMED_MEDIA_GROUP_TYPE_AUDIO,
|
|
121
|
-
LANGUAGE_ENGLISH,
|
|
122
122
|
} from '../constants';
|
|
123
123
|
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
124
124
|
import ParameterError from '../common/errors/parameter';
|
|
@@ -5726,234 +5726,252 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5726
5726
|
* @returns {undefined}
|
|
5727
5727
|
*/
|
|
5728
5728
|
setupSdpListeners = () => {
|
|
5729
|
-
this.mediaProperties.webrtcMediaConnection.on(
|
|
5730
|
-
|
|
5731
|
-
|
|
5729
|
+
this.mediaProperties.webrtcMediaConnection.on(
|
|
5730
|
+
MediaConnectionEventNames.REMOTE_SDP_ANSWER_PROCESSED,
|
|
5731
|
+
() => {
|
|
5732
|
+
// @ts-ignore
|
|
5733
|
+
const cdl = this.webex.internal.newMetrics.callDiagnosticLatencies;
|
|
5732
5734
|
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5735
|
+
// @ts-ignore
|
|
5736
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5737
|
+
name: 'client.media-engine.remote-sdp-received',
|
|
5738
|
+
options: {meetingId: this.id},
|
|
5739
|
+
});
|
|
5740
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_OFFER_TO_ANSWER_LATENCY, {
|
|
5741
|
+
correlation_id: this.correlationId,
|
|
5742
|
+
latency: cdl.getLocalSDPGenRemoteSDPRecv(),
|
|
5743
|
+
meetingId: this.id,
|
|
5744
|
+
});
|
|
5743
5745
|
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5746
|
+
if (this.deferSDPAnswer) {
|
|
5747
|
+
this.deferSDPAnswer.resolve();
|
|
5748
|
+
clearTimeout(this.sdpResponseTimer);
|
|
5749
|
+
this.sdpResponseTimer = undefined;
|
|
5750
|
+
}
|
|
5748
5751
|
}
|
|
5749
|
-
|
|
5752
|
+
);
|
|
5750
5753
|
|
|
5751
|
-
this.mediaProperties.webrtcMediaConnection.on(
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5754
|
+
this.mediaProperties.webrtcMediaConnection.on(
|
|
5755
|
+
MediaConnectionEventNames.LOCAL_SDP_OFFER_GENERATED,
|
|
5756
|
+
() => {
|
|
5757
|
+
// @ts-ignore
|
|
5758
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5759
|
+
name: 'client.media-engine.local-sdp-generated',
|
|
5760
|
+
options: {meetingId: this.id},
|
|
5761
|
+
});
|
|
5757
5762
|
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5763
|
+
// Instantiate Defer so that the SDP offer/answer exchange timeout can start, see waitForRemoteSDPAnswer()
|
|
5764
|
+
this.deferSDPAnswer = new Defer();
|
|
5765
|
+
}
|
|
5766
|
+
);
|
|
5761
5767
|
|
|
5762
|
-
this.mediaProperties.webrtcMediaConnection.on(
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5768
|
+
this.mediaProperties.webrtcMediaConnection.on(
|
|
5769
|
+
MediaConnectionEventNames.LOCAL_SDP_ANSWER_GENERATED,
|
|
5770
|
+
() => {
|
|
5771
|
+
// we are sending "remote-sdp-received" only after we've generated the answer - this indicates that we've fully processed that incoming offer
|
|
5772
|
+
// @ts-ignore
|
|
5773
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5774
|
+
name: 'client.media-engine.remote-sdp-received',
|
|
5775
|
+
options: {meetingId: this.id},
|
|
5776
|
+
});
|
|
5777
|
+
}
|
|
5778
|
+
);
|
|
5770
5779
|
};
|
|
5771
5780
|
|
|
5772
5781
|
setupMediaConnectionListeners = () => {
|
|
5773
5782
|
this.setupSdpListeners();
|
|
5774
5783
|
|
|
5775
|
-
this.mediaProperties.webrtcMediaConnection.on(
|
|
5784
|
+
this.mediaProperties.webrtcMediaConnection.on(MediaConnectionEventNames.ROAP_STARTED, () => {
|
|
5776
5785
|
this.isRoapInProgress = true;
|
|
5777
5786
|
});
|
|
5778
5787
|
|
|
5779
|
-
this.mediaProperties.webrtcMediaConnection.on(
|
|
5788
|
+
this.mediaProperties.webrtcMediaConnection.on(MediaConnectionEventNames.ROAP_DONE, () => {
|
|
5780
5789
|
this.mediaNegotiatedEvent();
|
|
5781
5790
|
this.isRoapInProgress = false;
|
|
5782
5791
|
this.processNextQueuedMediaUpdate();
|
|
5783
5792
|
});
|
|
5784
5793
|
|
|
5785
|
-
this.mediaProperties.webrtcMediaConnection.on(
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
switch (event.roapMessage.messageType) {
|
|
5791
|
-
case 'OK':
|
|
5792
|
-
logRequest(
|
|
5793
|
-
this.roap.sendRoapOK({
|
|
5794
|
-
seq: event.roapMessage.seq,
|
|
5795
|
-
mediaId: this.mediaId,
|
|
5796
|
-
correlationId: this.correlationId,
|
|
5797
|
-
}),
|
|
5798
|
-
{
|
|
5799
|
-
logText: `${LOG_HEADER} Roap OK`,
|
|
5800
|
-
}
|
|
5801
|
-
);
|
|
5802
|
-
break;
|
|
5794
|
+
this.mediaProperties.webrtcMediaConnection.on(
|
|
5795
|
+
MediaConnectionEventNames.ROAP_FAILURE,
|
|
5796
|
+
this.handleRoapFailure
|
|
5797
|
+
);
|
|
5803
5798
|
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5799
|
+
this.mediaProperties.webrtcMediaConnection.on(
|
|
5800
|
+
MediaConnectionEventNames.ROAP_MESSAGE_TO_SEND,
|
|
5801
|
+
(event) => {
|
|
5802
|
+
const LOG_HEADER = `Meeting:index#setupMediaConnectionListeners.ROAP_MESSAGE_TO_SEND --> correlationId=${this.correlationId}`;
|
|
5803
|
+
|
|
5804
|
+
switch (event.roapMessage.messageType) {
|
|
5805
|
+
case 'OK':
|
|
5806
|
+
logRequest(
|
|
5807
|
+
this.roap.sendRoapOK({
|
|
5809
5808
|
seq: event.roapMessage.seq,
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
})
|
|
5813
|
-
.then(({roapAnswer}) => {
|
|
5814
|
-
if (roapAnswer) {
|
|
5815
|
-
LoggerProxy.logger.log(`${LOG_HEADER} received Roap ANSWER in http response`);
|
|
5816
|
-
|
|
5817
|
-
this.roapMessageReceived(roapAnswer);
|
|
5818
|
-
}
|
|
5809
|
+
mediaId: this.mediaId,
|
|
5810
|
+
correlationId: this.correlationId,
|
|
5819
5811
|
}),
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
this.webex.internal.newMetrics.submitClientEvent({
|
|
5826
|
-
name: 'client.media-engine.remote-sdp-received',
|
|
5827
|
-
payload: {
|
|
5828
|
-
canProceed: false,
|
|
5829
|
-
errors: [
|
|
5830
|
-
// @ts-ignore
|
|
5831
|
-
this.webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode(
|
|
5832
|
-
{
|
|
5833
|
-
clientErrorCode: CALL_DIAGNOSTIC_CONFIG.MISSING_ROAP_ANSWER_CLIENT_CODE,
|
|
5834
|
-
}
|
|
5835
|
-
),
|
|
5836
|
-
],
|
|
5837
|
-
},
|
|
5838
|
-
options: {meetingId: this.id, rawError: error},
|
|
5839
|
-
});
|
|
5812
|
+
{
|
|
5813
|
+
logText: `${LOG_HEADER} Roap OK`,
|
|
5814
|
+
}
|
|
5815
|
+
);
|
|
5816
|
+
break;
|
|
5840
5817
|
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5818
|
+
case 'OFFER':
|
|
5819
|
+
logRequest(
|
|
5820
|
+
this.roap
|
|
5821
|
+
.sendRoapMediaRequest({
|
|
5822
|
+
sdp: event.roapMessage.sdp,
|
|
5823
|
+
seq: event.roapMessage.seq,
|
|
5824
|
+
tieBreaker: event.roapMessage.tieBreaker,
|
|
5825
|
+
meeting: this, // or can pass meeting ID
|
|
5826
|
+
})
|
|
5827
|
+
.then(({roapAnswer}) => {
|
|
5828
|
+
if (roapAnswer) {
|
|
5829
|
+
LoggerProxy.logger.log(`${LOG_HEADER} received Roap ANSWER in http response`);
|
|
5830
|
+
|
|
5831
|
+
this.roapMessageReceived(roapAnswer);
|
|
5832
|
+
}
|
|
5833
|
+
}),
|
|
5834
|
+
{
|
|
5835
|
+
logText: `${LOG_HEADER} Roap Offer`,
|
|
5836
|
+
}
|
|
5837
|
+
).catch((error) => {
|
|
5838
|
+
// @ts-ignore
|
|
5839
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5840
|
+
name: 'client.media-engine.remote-sdp-received',
|
|
5841
|
+
payload: {
|
|
5842
|
+
canProceed: false,
|
|
5843
|
+
errors: [
|
|
5844
|
+
// @ts-ignore
|
|
5845
|
+
this.webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode(
|
|
5846
|
+
{
|
|
5847
|
+
clientErrorCode: CALL_DIAGNOSTIC_CONFIG.MISSING_ROAP_ANSWER_CLIENT_CODE,
|
|
5848
|
+
}
|
|
5849
|
+
),
|
|
5850
|
+
],
|
|
5851
|
+
},
|
|
5852
|
+
options: {meetingId: this.id, rawError: error},
|
|
5853
|
+
});
|
|
5846
5854
|
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
mediaId: this.mediaId,
|
|
5853
|
-
correlationId: this.correlationId,
|
|
5854
|
-
}),
|
|
5855
|
-
{
|
|
5856
|
-
logText: `${LOG_HEADER} Roap Answer`,
|
|
5857
|
-
}
|
|
5858
|
-
).catch((error) => {
|
|
5859
|
-
const metricName = BEHAVIORAL_METRICS.ROAP_ANSWER_FAILURE;
|
|
5860
|
-
const data = {
|
|
5861
|
-
correlation_id: this.correlationId,
|
|
5862
|
-
locus_id: this.locusUrl.split('/').pop(),
|
|
5863
|
-
reason: error.message,
|
|
5864
|
-
stack: error.stack,
|
|
5865
|
-
};
|
|
5866
|
-
const metadata = {
|
|
5867
|
-
type: error.name,
|
|
5868
|
-
};
|
|
5855
|
+
this.deferSDPAnswer.reject(new Error('failed to send ROAP SDP offer'));
|
|
5856
|
+
clearTimeout(this.sdpResponseTimer);
|
|
5857
|
+
this.sdpResponseTimer = undefined;
|
|
5858
|
+
});
|
|
5859
|
+
break;
|
|
5869
5860
|
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5861
|
+
case 'ANSWER':
|
|
5862
|
+
logRequest(
|
|
5863
|
+
this.roap.sendRoapAnswer({
|
|
5864
|
+
sdp: event.roapMessage.sdp,
|
|
5865
|
+
seq: event.roapMessage.seq,
|
|
5866
|
+
mediaId: this.mediaId,
|
|
5867
|
+
correlationId: this.correlationId,
|
|
5868
|
+
}),
|
|
5869
|
+
{
|
|
5870
|
+
logText: `${LOG_HEADER} Roap Answer`,
|
|
5871
|
+
}
|
|
5872
|
+
).catch((error) => {
|
|
5873
|
+
const metricName = BEHAVIORAL_METRICS.ROAP_ANSWER_FAILURE;
|
|
5874
|
+
const data = {
|
|
5875
|
+
correlation_id: this.correlationId,
|
|
5876
|
+
locus_id: this.locusUrl.split('/').pop(),
|
|
5877
|
+
reason: error.message,
|
|
5878
|
+
stack: error.stack,
|
|
5879
|
+
};
|
|
5880
|
+
const metadata = {
|
|
5881
|
+
type: error.name,
|
|
5882
|
+
};
|
|
5873
5883
|
|
|
5874
|
-
|
|
5875
|
-
if (
|
|
5876
|
-
event.roapMessage.errorType === ErrorType.CONFLICT ||
|
|
5877
|
-
event.roapMessage.errorType === ErrorType.DOUBLECONFLICT
|
|
5878
|
-
) {
|
|
5879
|
-
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_GLARE_CONDITION, {
|
|
5880
|
-
correlation_id: this.correlationId,
|
|
5881
|
-
locus_id: this.locusUrl.split('/').pop(),
|
|
5882
|
-
sequence: event.roapMessage.seq,
|
|
5884
|
+
Metrics.sendBehavioralMetric(metricName, data, metadata);
|
|
5883
5885
|
});
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5886
|
+
break;
|
|
5887
|
+
|
|
5888
|
+
case 'ERROR':
|
|
5889
|
+
if (
|
|
5890
|
+
event.roapMessage.errorType === ErrorType.CONFLICT ||
|
|
5891
|
+
event.roapMessage.errorType === ErrorType.DOUBLECONFLICT
|
|
5892
|
+
) {
|
|
5893
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_GLARE_CONDITION, {
|
|
5894
|
+
correlation_id: this.correlationId,
|
|
5895
|
+
locus_id: this.locusUrl.split('/').pop(),
|
|
5896
|
+
sequence: event.roapMessage.seq,
|
|
5897
|
+
});
|
|
5894
5898
|
}
|
|
5895
|
-
|
|
5896
|
-
|
|
5899
|
+
logRequest(
|
|
5900
|
+
this.roap.sendRoapError({
|
|
5901
|
+
seq: event.roapMessage.seq,
|
|
5902
|
+
errorType: event.roapMessage.errorType,
|
|
5903
|
+
mediaId: this.mediaId,
|
|
5904
|
+
correlationId: this.correlationId,
|
|
5905
|
+
}),
|
|
5906
|
+
{
|
|
5907
|
+
logText: `${LOG_HEADER} Roap Error (${event.roapMessage.errorType})`,
|
|
5908
|
+
}
|
|
5909
|
+
);
|
|
5910
|
+
break;
|
|
5897
5911
|
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5912
|
+
default:
|
|
5913
|
+
LoggerProxy.logger.error(
|
|
5914
|
+
`${LOG_HEADER} Unsupported message type: ${event.roapMessage.messageType}`
|
|
5915
|
+
);
|
|
5916
|
+
break;
|
|
5917
|
+
}
|
|
5903
5918
|
}
|
|
5904
|
-
|
|
5919
|
+
);
|
|
5905
5920
|
|
|
5906
5921
|
// eslint-disable-next-line no-param-reassign
|
|
5907
|
-
this.mediaProperties.webrtcMediaConnection.on(
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
const mediaTrack = event.track;
|
|
5916
|
-
const remoteStream = new RemoteStream(MediaUtil.createMediaStream([mediaTrack]));
|
|
5922
|
+
this.mediaProperties.webrtcMediaConnection.on(
|
|
5923
|
+
MediaConnectionEventNames.REMOTE_TRACK_ADDED,
|
|
5924
|
+
(event) => {
|
|
5925
|
+
LoggerProxy.logger.log(
|
|
5926
|
+
`Meeting:index#setupMediaConnectionListeners --> REMOTE_TRACK_ADDED event received for webrtcMediaConnection: ${JSON.stringify(
|
|
5927
|
+
event
|
|
5928
|
+
)}`
|
|
5929
|
+
);
|
|
5917
5930
|
|
|
5918
|
-
|
|
5919
|
-
|
|
5931
|
+
if (event.track) {
|
|
5932
|
+
const mediaTrack = event.track;
|
|
5933
|
+
const remoteStream = new RemoteStream(MediaUtil.createMediaStream([mediaTrack]));
|
|
5934
|
+
|
|
5935
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
5936
|
+
let eventType;
|
|
5937
|
+
|
|
5938
|
+
switch (event.type) {
|
|
5939
|
+
case RemoteTrackType.AUDIO:
|
|
5940
|
+
eventType = EVENT_TYPES.REMOTE_AUDIO;
|
|
5941
|
+
this.mediaProperties.setRemoteAudioStream(remoteStream);
|
|
5942
|
+
break;
|
|
5943
|
+
case RemoteTrackType.VIDEO:
|
|
5944
|
+
eventType = EVENT_TYPES.REMOTE_VIDEO;
|
|
5945
|
+
this.mediaProperties.setRemoteVideoStream(remoteStream);
|
|
5946
|
+
break;
|
|
5947
|
+
case RemoteTrackType.SCREENSHARE_VIDEO:
|
|
5948
|
+
eventType = EVENT_TYPES.REMOTE_SHARE;
|
|
5949
|
+
this.mediaProperties.setRemoteShareStream(remoteStream);
|
|
5950
|
+
break;
|
|
5951
|
+
default: {
|
|
5952
|
+
LoggerProxy.logger.log(
|
|
5953
|
+
'Meeting:index#setupMediaConnectionListeners --> unexpected track'
|
|
5954
|
+
);
|
|
5955
|
+
}
|
|
5956
|
+
}
|
|
5920
5957
|
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
break;
|
|
5934
|
-
default: {
|
|
5935
|
-
LoggerProxy.logger.log(
|
|
5936
|
-
'Meeting:index#setupMediaConnectionListeners --> unexpected track'
|
|
5958
|
+
if (eventType && mediaTrack) {
|
|
5959
|
+
Trigger.trigger(
|
|
5960
|
+
this,
|
|
5961
|
+
{
|
|
5962
|
+
file: 'meeting/index',
|
|
5963
|
+
function: 'setupRemoteTrackListener:MediaConnectionEventNames.REMOTE_TRACK_ADDED',
|
|
5964
|
+
},
|
|
5965
|
+
EVENT_TRIGGERS.MEDIA_READY,
|
|
5966
|
+
{
|
|
5967
|
+
type: eventType,
|
|
5968
|
+
stream: remoteStream.outputStream,
|
|
5969
|
+
}
|
|
5937
5970
|
);
|
|
5938
5971
|
}
|
|
5939
5972
|
}
|
|
5940
|
-
|
|
5941
|
-
if (eventType && mediaTrack) {
|
|
5942
|
-
Trigger.trigger(
|
|
5943
|
-
this,
|
|
5944
|
-
{
|
|
5945
|
-
file: 'meeting/index',
|
|
5946
|
-
function: 'setupRemoteTrackListener:Event.REMOTE_TRACK_ADDED',
|
|
5947
|
-
},
|
|
5948
|
-
EVENT_TRIGGERS.MEDIA_READY,
|
|
5949
|
-
{
|
|
5950
|
-
type: eventType,
|
|
5951
|
-
stream: remoteStream.outputStream,
|
|
5952
|
-
}
|
|
5953
|
-
);
|
|
5954
|
-
}
|
|
5955
5973
|
}
|
|
5956
|
-
|
|
5974
|
+
);
|
|
5957
5975
|
|
|
5958
5976
|
this.connectionStateHandler = new ConnectionStateHandler(
|
|
5959
5977
|
this.mediaProperties.webrtcMediaConnection
|
|
@@ -5988,7 +6006,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5988
6006
|
|
|
5989
6007
|
// @ts-ignore
|
|
5990
6008
|
const cdl = this.webex.internal.newMetrics.callDiagnosticLatencies;
|
|
5991
|
-
|
|
5992
6009
|
switch (event.state) {
|
|
5993
6010
|
case ConnectionState.Connecting:
|
|
5994
6011
|
if (!this.hasMediaConnectionConnectedAtLeastOnce) {
|
|
@@ -6045,25 +6062,28 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6045
6062
|
}
|
|
6046
6063
|
});
|
|
6047
6064
|
|
|
6048
|
-
this.mediaProperties.webrtcMediaConnection.on(
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6065
|
+
this.mediaProperties.webrtcMediaConnection.on(
|
|
6066
|
+
MediaConnectionEventNames.ACTIVE_SPEAKERS_CHANGED,
|
|
6067
|
+
(csis) => {
|
|
6068
|
+
Trigger.trigger(
|
|
6069
|
+
this,
|
|
6070
|
+
{
|
|
6071
|
+
file: 'meeting/index',
|
|
6072
|
+
function: 'setupMediaConnectionListeners',
|
|
6073
|
+
},
|
|
6074
|
+
EVENT_TRIGGERS.ACTIVE_SPEAKER_CHANGED,
|
|
6075
|
+
{
|
|
6076
|
+
memberIds: csis
|
|
6077
|
+
// @ts-ignore
|
|
6078
|
+
.map((csi) => this.members.findMemberByCsi(csi)?.id)
|
|
6079
|
+
.filter((item) => item !== undefined),
|
|
6080
|
+
}
|
|
6081
|
+
);
|
|
6082
|
+
}
|
|
6083
|
+
);
|
|
6064
6084
|
|
|
6065
6085
|
this.mediaProperties.webrtcMediaConnection.on(
|
|
6066
|
-
|
|
6086
|
+
MediaConnectionEventNames.VIDEO_SOURCES_COUNT_CHANGED,
|
|
6067
6087
|
(numTotalSources, numLiveSources, mediaContent) => {
|
|
6068
6088
|
Trigger.trigger(
|
|
6069
6089
|
this,
|
|
@@ -6086,7 +6106,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6086
6106
|
);
|
|
6087
6107
|
|
|
6088
6108
|
this.mediaProperties.webrtcMediaConnection.on(
|
|
6089
|
-
|
|
6109
|
+
MediaConnectionEventNames.AUDIO_SOURCES_COUNT_CHANGED,
|
|
6090
6110
|
(numTotalSources, numLiveSources, mediaContent) => {
|
|
6091
6111
|
Trigger.trigger(
|
|
6092
6112
|
this,
|
|
@@ -6105,37 +6125,43 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6105
6125
|
);
|
|
6106
6126
|
|
|
6107
6127
|
this.iceCandidateErrors.clear();
|
|
6108
|
-
this.mediaProperties.webrtcMediaConnection.on(
|
|
6109
|
-
|
|
6110
|
-
|
|
6128
|
+
this.mediaProperties.webrtcMediaConnection.on(
|
|
6129
|
+
MediaConnectionEventNames.ICE_CANDIDATE_ERROR,
|
|
6130
|
+
(event) => {
|
|
6131
|
+
const {errorCode} = event.error;
|
|
6132
|
+
let {errorText} = event.error;
|
|
6111
6133
|
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6134
|
+
if (
|
|
6135
|
+
errorCode === 600 &&
|
|
6136
|
+
errorText === 'Address not associated with the desired network interface.'
|
|
6137
|
+
) {
|
|
6138
|
+
return;
|
|
6139
|
+
}
|
|
6118
6140
|
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6141
|
+
if (errorText.endsWith('.')) {
|
|
6142
|
+
errorText = errorText.slice(0, -1);
|
|
6143
|
+
}
|
|
6122
6144
|
|
|
6123
|
-
|
|
6124
|
-
|
|
6145
|
+
errorText = errorText.toLowerCase();
|
|
6146
|
+
errorText = errorText.replace(/ /g, '_');
|
|
6125
6147
|
|
|
6126
|
-
|
|
6148
|
+
const error = `${errorCode}_${errorText}`;
|
|
6127
6149
|
|
|
6128
|
-
|
|
6150
|
+
const count = this.iceCandidateErrors.get(error) || 0;
|
|
6129
6151
|
|
|
6130
|
-
|
|
6131
|
-
|
|
6152
|
+
this.iceCandidateErrors.set(error, count + 1);
|
|
6153
|
+
}
|
|
6154
|
+
);
|
|
6132
6155
|
|
|
6133
6156
|
this.iceCandidatesCount = 0;
|
|
6134
|
-
this.mediaProperties.webrtcMediaConnection.on(
|
|
6135
|
-
|
|
6136
|
-
|
|
6157
|
+
this.mediaProperties.webrtcMediaConnection.on(
|
|
6158
|
+
MediaConnectionEventNames.ICE_CANDIDATE,
|
|
6159
|
+
(event) => {
|
|
6160
|
+
if (event.candidate) {
|
|
6161
|
+
this.iceCandidatesCount += 1;
|
|
6162
|
+
}
|
|
6137
6163
|
}
|
|
6138
|
-
|
|
6164
|
+
);
|
|
6139
6165
|
};
|
|
6140
6166
|
|
|
6141
6167
|
/**
|
|
@@ -6145,7 +6171,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6145
6171
|
* @memberof Meetings
|
|
6146
6172
|
*/
|
|
6147
6173
|
setupStatsAnalyzerEventHandlers = () => {
|
|
6148
|
-
this.statsAnalyzer.on(
|
|
6174
|
+
this.statsAnalyzer.on(StatsAnalyzerEventNames.MEDIA_QUALITY, (options) => {
|
|
6149
6175
|
// TODO: might have to send the same event to the developer
|
|
6150
6176
|
// Add ip address info if geo hint is present
|
|
6151
6177
|
// @ts-ignore fix type
|
|
@@ -6159,14 +6185,15 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6159
6185
|
name: 'client.mediaquality.event',
|
|
6160
6186
|
options: {
|
|
6161
6187
|
meetingId: this.id,
|
|
6162
|
-
networkType: options.networkType,
|
|
6188
|
+
networkType: options.data.networkType,
|
|
6163
6189
|
},
|
|
6164
6190
|
payload: {
|
|
6165
6191
|
intervals: [options.data],
|
|
6166
6192
|
},
|
|
6167
6193
|
});
|
|
6168
6194
|
});
|
|
6169
|
-
|
|
6195
|
+
|
|
6196
|
+
this.statsAnalyzer.on(StatsAnalyzerEventNames.LOCAL_MEDIA_STARTED, (data) => {
|
|
6170
6197
|
Trigger.trigger(
|
|
6171
6198
|
this,
|
|
6172
6199
|
{
|
|
@@ -6180,28 +6207,28 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6180
6207
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
6181
6208
|
name: 'client.media.tx.start',
|
|
6182
6209
|
payload: {
|
|
6183
|
-
mediaType: data.
|
|
6184
|
-
shareInstanceId: data.
|
|
6210
|
+
mediaType: data.mediaType,
|
|
6211
|
+
shareInstanceId: data.mediaType === 'share' ? this.localShareInstanceId : undefined,
|
|
6185
6212
|
},
|
|
6186
6213
|
options: {
|
|
6187
6214
|
meetingId: this.id,
|
|
6188
6215
|
},
|
|
6189
6216
|
});
|
|
6190
6217
|
});
|
|
6191
|
-
this.statsAnalyzer.on(
|
|
6218
|
+
this.statsAnalyzer.on(StatsAnalyzerEventNames.LOCAL_MEDIA_STOPPED, (data) => {
|
|
6192
6219
|
// @ts-ignore
|
|
6193
6220
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
6194
6221
|
name: 'client.media.tx.stop',
|
|
6195
6222
|
payload: {
|
|
6196
|
-
mediaType: data.
|
|
6197
|
-
shareInstanceId: data.
|
|
6223
|
+
mediaType: data.mediaType,
|
|
6224
|
+
shareInstanceId: data.mediaType === 'share' ? this.localShareInstanceId : undefined,
|
|
6198
6225
|
},
|
|
6199
6226
|
options: {
|
|
6200
6227
|
meetingId: this.id,
|
|
6201
6228
|
},
|
|
6202
6229
|
});
|
|
6203
6230
|
});
|
|
6204
|
-
this.statsAnalyzer.on(
|
|
6231
|
+
this.statsAnalyzer.on(StatsAnalyzerEventNames.REMOTE_MEDIA_STARTED, (data) => {
|
|
6205
6232
|
Trigger.trigger(
|
|
6206
6233
|
this,
|
|
6207
6234
|
{
|
|
@@ -6215,15 +6242,15 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6215
6242
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
6216
6243
|
name: 'client.media.rx.start',
|
|
6217
6244
|
payload: {
|
|
6218
|
-
mediaType: data.
|
|
6219
|
-
shareInstanceId: data.
|
|
6245
|
+
mediaType: data.mediaType,
|
|
6246
|
+
shareInstanceId: data.mediaType === 'share' ? this.remoteShareInstanceId : undefined,
|
|
6220
6247
|
},
|
|
6221
6248
|
options: {
|
|
6222
6249
|
meetingId: this.id,
|
|
6223
6250
|
},
|
|
6224
6251
|
});
|
|
6225
6252
|
|
|
6226
|
-
if (data.
|
|
6253
|
+
if (data.mediaType === 'share') {
|
|
6227
6254
|
// @ts-ignore
|
|
6228
6255
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
6229
6256
|
name: 'client.media.render.start',
|
|
@@ -6237,20 +6264,20 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6237
6264
|
});
|
|
6238
6265
|
}
|
|
6239
6266
|
});
|
|
6240
|
-
this.statsAnalyzer.on(
|
|
6267
|
+
this.statsAnalyzer.on(StatsAnalyzerEventNames.REMOTE_MEDIA_STOPPED, (data) => {
|
|
6241
6268
|
// @ts-ignore
|
|
6242
6269
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
6243
6270
|
name: 'client.media.rx.stop',
|
|
6244
6271
|
payload: {
|
|
6245
|
-
mediaType: data.
|
|
6246
|
-
shareInstanceId: data.
|
|
6272
|
+
mediaType: data.mediaType,
|
|
6273
|
+
shareInstanceId: data.mediaType === 'share' ? this.remoteShareInstanceId : undefined,
|
|
6247
6274
|
},
|
|
6248
6275
|
options: {
|
|
6249
6276
|
meetingId: this.id,
|
|
6250
6277
|
},
|
|
6251
6278
|
});
|
|
6252
6279
|
|
|
6253
|
-
if (data.
|
|
6280
|
+
if (data.mediaType === 'share') {
|
|
6254
6281
|
// @ts-ignore
|
|
6255
6282
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
6256
6283
|
name: 'client.media.render.stop',
|
|
@@ -6468,7 +6495,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6468
6495
|
this.statsAnalyzer = new StatsAnalyzer({
|
|
6469
6496
|
// @ts-ignore - config coming from registerPlugin
|
|
6470
6497
|
config: this.config.stats,
|
|
6471
|
-
receiveSlotCallback: (ssrc: number) => this.receiveSlotManager.findReceiveSlotBySsrc(ssrc),
|
|
6472
6498
|
networkQualityMonitor: this.networkQualityMonitor,
|
|
6473
6499
|
isMultistream: this.isMultistream,
|
|
6474
6500
|
});
|