@wazo/sdk 0.37.21 → 0.37.25
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/wazo-sdk.js +5 -5
- package/esm/__tests__/api-client.test.js +36 -5
- package/esm/__tests__/web-rtc-client.test.js +77 -66
- package/esm/api/call-logd.js +7 -0
- package/esm/api/calld.js +10 -0
- package/esm/api/chatd.js +7 -0
- package/esm/api/confd.js +13 -5
- package/esm/api/ctid-ng.js +10 -0
- package/esm/api/dird.js +3 -0
- package/esm/api-client.js +36 -5
- package/esm/checker/Checker.js +77 -66
- package/esm/checker/checks/aor.js +36 -5
- package/esm/checker/checks/api.js +36 -5
- package/esm/checker/checks/index.js +77 -66
- package/esm/checker/checks/webrtc-transport.js +77 -66
- package/esm/checker/checks/webrtc.js +77 -66
- package/esm/domain/AdHocAPIConference.js +36 -5
- package/esm/domain/Call.js +3 -0
- package/esm/domain/CallLog.js +7 -0
- package/esm/domain/ChatMessage.js +4 -0
- package/esm/domain/ChatRoom.js +3 -0
- package/esm/domain/Contact.js +3 -0
- package/esm/domain/Features.js +36 -5
- package/esm/domain/Meeting.js +15 -5
- package/esm/domain/Phone/CTIPhone.js +40 -5
- package/esm/domain/Phone/WebRTCPhone.js +45 -16
- package/esm/domain/Recording.js +3 -0
- package/esm/domain/Voicemail.js +3 -0
- package/esm/domain/__tests__/Call.test.js +3 -0
- package/esm/domain/__tests__/CallLog.test.js +7 -0
- package/esm/domain/__tests__/Contact.test.js +3 -0
- package/esm/domain/__tests__/Meeting.test.js +144 -0
- package/esm/domain/__tests__/Voicemail.test.js +3 -0
- package/esm/index.js +125 -81
- package/esm/lib/WazoSessionDescriptionHandler.js +0 -38
- package/esm/service/CallApi.js +36 -5
- package/esm/service/getApiClient.js +36 -5
- package/esm/simple/Auth.js +125 -81
- package/esm/simple/Configuration.js +125 -81
- package/esm/simple/Directory.js +36 -5
- package/esm/simple/Phone.js +125 -81
- package/esm/simple/index.js +125 -81
- package/esm/simple/room/LocalParticipant.js +125 -81
- package/esm/simple/room/Participant.js +125 -81
- package/esm/simple/room/RemoteParticipant.js +125 -81
- package/esm/simple/room/Room.js +125 -81
- package/esm/simple/room/SipRoom.js +125 -81
- package/esm/simple/room/Stream.js +125 -81
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +125 -81
- package/esm/simple/utils.js +125 -81
- package/esm/types/WebSocketMessage.js +1 -1
- package/esm/web-rtc-client.js +77 -66
- package/lib/__tests__/api-client.test.js +36 -5
- package/lib/__tests__/web-rtc-client.test.js +77 -66
- package/lib/api/call-logd.js +7 -0
- package/lib/api/calld.js +10 -0
- package/lib/api/chatd.js +7 -0
- package/lib/api/confd.js +13 -5
- package/lib/api/ctid-ng.js +10 -0
- package/lib/api/dird.js +3 -0
- package/lib/api-client.js +36 -5
- package/lib/checker/Checker.js +77 -66
- package/lib/checker/checks/aor.js +36 -5
- package/lib/checker/checks/api.js +36 -5
- package/lib/checker/checks/index.js +77 -66
- package/lib/checker/checks/webrtc-transport.js +77 -66
- package/lib/checker/checks/webrtc.js +77 -66
- package/lib/domain/AdHocAPIConference.js +36 -5
- package/lib/domain/Call.js +3 -0
- package/lib/domain/CallLog.js +7 -0
- package/lib/domain/ChatMessage.js +4 -0
- package/lib/domain/ChatRoom.js +3 -0
- package/lib/domain/Contact.js +3 -0
- package/lib/domain/Features.js +36 -5
- package/lib/domain/Meeting.js +19 -5
- package/lib/domain/Phone/CTIPhone.js +40 -5
- package/lib/domain/Phone/WebRTCPhone.js +45 -16
- package/lib/domain/Recording.js +3 -0
- package/lib/domain/Voicemail.js +3 -0
- package/lib/domain/__tests__/Call.test.js +3 -0
- package/lib/domain/__tests__/CallLog.test.js +7 -0
- package/lib/domain/__tests__/Contact.test.js +3 -0
- package/lib/domain/__tests__/Meeting.test.js +150 -0
- package/lib/domain/__tests__/Voicemail.test.js +3 -0
- package/lib/index.js +125 -81
- package/lib/lib/WazoSessionDescriptionHandler.js +0 -38
- package/lib/service/CallApi.js +36 -5
- package/lib/service/getApiClient.js +36 -5
- package/lib/simple/Auth.js +125 -81
- package/lib/simple/Configuration.js +125 -81
- package/lib/simple/Directory.js +36 -5
- package/lib/simple/Phone.js +125 -81
- package/lib/simple/index.js +125 -81
- package/lib/simple/room/LocalParticipant.js +125 -81
- package/lib/simple/room/Participant.js +125 -81
- package/lib/simple/room/RemoteParticipant.js +125 -81
- package/lib/simple/room/Room.js +125 -81
- package/lib/simple/room/SipRoom.js +125 -81
- package/lib/simple/room/Stream.js +125 -81
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +125 -81
- package/lib/simple/utils.js +125 -81
- package/lib/types/WebSocketMessage.js +2 -0
- package/lib/web-rtc-client.js +77 -66
- package/package.json +1 -1
- package/src/domain/Call.js +3 -0
- package/src/domain/CallLog.js +4 -0
- package/src/domain/ChatMessage.js +4 -0
- package/src/domain/ChatRoom.js +3 -0
- package/src/domain/Contact.js +3 -0
- package/src/domain/Meeting.js +15 -5
- package/src/domain/Phone/CTIPhone.js +4 -0
- package/src/domain/Phone/Phone.js +2 -0
- package/src/domain/Phone/WebRTCPhone.js +45 -16
- package/src/domain/Recording.js +3 -0
- package/src/domain/Voicemail.js +3 -0
- package/src/domain/__tests__/Meeting.test.js +50 -0
- package/src/lib/WazoSessionDescriptionHandler.js +1 -35
- package/src/web-rtc-client.js +41 -23
|
@@ -724,10 +724,6 @@ const getSrflxOrRelay = (candidates ) =>
|
|
|
724
724
|
candidates
|
|
725
725
|
.filter(candidate => candidate && (candidate.type === 'srflx' || candidate.type === 'relay'));
|
|
726
726
|
|
|
727
|
-
const areCandidateValid = (candidates ) =>
|
|
728
|
-
getSrflxOrRelay(candidates)
|
|
729
|
-
.length > 0;
|
|
730
|
-
|
|
731
727
|
const getVideoDirection = (sdp ) => {
|
|
732
728
|
const parsedSdp = sdpParser.parse(sdp);
|
|
733
729
|
const videoMedia = parsedSdp.media.find(media => media.type === 'video');
|
|
@@ -780,8 +776,6 @@ const fixSdp = (sdp , candidates , forcePort = true)
|
|
|
780
776
|
/* global RTCSessionDescriptionInit, navigator */
|
|
781
777
|
|
|
782
778
|
const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
|
|
783
|
-
const MAX_WAIT_FOR_ICE_TRIES = 20;
|
|
784
|
-
const WAIT_FOR_ICE_TIMEOUT = 500;
|
|
785
779
|
|
|
786
780
|
// Customized mediaStreamFactory allowing to send screensharing stream directory when upgrading
|
|
787
781
|
const wazoMediaStreamFactory = (constraints ) => {
|
|
@@ -971,38 +965,6 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
971
965
|
this._peerConnection = undefined;
|
|
972
966
|
}
|
|
973
967
|
|
|
974
|
-
async _waitForValidGatheredIce() {
|
|
975
|
-
let tries = 0;
|
|
976
|
-
|
|
977
|
-
while (!areCandidateValid(this.gatheredCandidates) && tries < MAX_WAIT_FOR_ICE_TRIES) {
|
|
978
|
-
wazoLogger.trace('SessionDescriptionHandler._waitForValidGatheredIce, waiting for ice', {
|
|
979
|
-
tries,
|
|
980
|
-
max: MAX_WAIT_FOR_ICE_TRIES,
|
|
981
|
-
});
|
|
982
|
-
|
|
983
|
-
tries++;
|
|
984
|
-
|
|
985
|
-
// eslint-disable-next-line no-await-in-loop
|
|
986
|
-
await new Promise(resolve => setTimeout(resolve, WAIT_FOR_ICE_TIMEOUT));
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
if (tries >= MAX_WAIT_FOR_ICE_TRIES) {
|
|
990
|
-
const errorMsg = 'No valid candidates found, can\'t answer the call';
|
|
991
|
-
const error = new Error(errorMsg);
|
|
992
|
-
wazoLogger.error(errorMsg, { tries, max: MAX_WAIT_FOR_ICE_TRIES });
|
|
993
|
-
|
|
994
|
-
// Emit an error, because sip.js catches the exception and switch to status Terminated.
|
|
995
|
-
this.eventEmitter.emit('error', error);
|
|
996
|
-
|
|
997
|
-
wazoLogger.error('No valid candidates found', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
// eslint-disable-next-line
|
|
1001
|
-
wazoLogger.trace('Found valid candidates', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
|
|
1002
|
-
|
|
1003
|
-
return this.getLocalSessionDescription();
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
968
|
// Overridden to send `inactive` in conference
|
|
1007
969
|
updateDirection(options , isConference = false,
|
|
1008
970
|
audioOnly = false) {
|
|
@@ -2112,6 +2074,9 @@ class Contact {
|
|
|
2112
2074
|
}
|
|
2113
2075
|
|
|
2114
2076
|
static parseMany(response ) {
|
|
2077
|
+
if (!response || !response.results) {
|
|
2078
|
+
return [];
|
|
2079
|
+
}
|
|
2115
2080
|
return response.results.map(r => Contact.parse(r, response.column_types));
|
|
2116
2081
|
}
|
|
2117
2082
|
|
|
@@ -3189,8 +3154,9 @@ class ExternalApp {
|
|
|
3189
3154
|
|
|
3190
3155
|
|
|
3191
3156
|
|
|
3192
|
-
|
|
3157
|
+
|
|
3193
3158
|
|
|
3159
|
+
|
|
3194
3160
|
|
|
3195
3161
|
|
|
3196
3162
|
class Meeting {
|
|
@@ -3201,9 +3167,10 @@ class Meeting {
|
|
|
3201
3167
|
|
|
3202
3168
|
|
|
3203
3169
|
|
|
3204
|
-
|
|
3170
|
+
|
|
3205
3171
|
|
|
3206
3172
|
|
|
3173
|
+
|
|
3207
3174
|
|
|
3208
3175
|
static parse(plain ) {
|
|
3209
3176
|
return new Meeting({
|
|
@@ -3213,12 +3180,16 @@ class Meeting {
|
|
|
3213
3180
|
ownerUuids: plain.owner_uuids,
|
|
3214
3181
|
port: plain.port,
|
|
3215
3182
|
uuid: plain.uuid,
|
|
3216
|
-
|
|
3183
|
+
extension: plain.exten,
|
|
3217
3184
|
persistent: plain.persistent,
|
|
3185
|
+
creationTime: moment(plain.creation_time).toDate(),
|
|
3218
3186
|
});
|
|
3219
3187
|
}
|
|
3220
3188
|
|
|
3221
3189
|
static parseMany(items ) {
|
|
3190
|
+
if (!items) {
|
|
3191
|
+
return [];
|
|
3192
|
+
}
|
|
3222
3193
|
return items.map(plain => Meeting.parse(plain));
|
|
3223
3194
|
}
|
|
3224
3195
|
|
|
@@ -3233,8 +3204,9 @@ class Meeting {
|
|
|
3233
3204
|
ownerUuids,
|
|
3234
3205
|
port,
|
|
3235
3206
|
uri,
|
|
3236
|
-
|
|
3207
|
+
extension,
|
|
3237
3208
|
persistent,
|
|
3209
|
+
creationTime,
|
|
3238
3210
|
} = {}) {
|
|
3239
3211
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
3240
3212
|
this.uri = uri;
|
|
@@ -3242,8 +3214,9 @@ class Meeting {
|
|
|
3242
3214
|
this.ownerUuids = ownerUuids;
|
|
3243
3215
|
this.port = port;
|
|
3244
3216
|
this.uuid = uuid;
|
|
3245
|
-
this.
|
|
3217
|
+
this.extension = extension;
|
|
3246
3218
|
this.persistent = persistent;
|
|
3219
|
+
this.creationTime = creationTime;
|
|
3247
3220
|
|
|
3248
3221
|
// Useful to compare instead of instanceof with minified code
|
|
3249
3222
|
this.type = 'Meeting';
|
|
@@ -3421,6 +3394,10 @@ class ChatMessage {
|
|
|
3421
3394
|
|
|
3422
3395
|
|
|
3423
3396
|
static parseMany(plain ) {
|
|
3397
|
+
if (!plain || !plain.items) {
|
|
3398
|
+
return [];
|
|
3399
|
+
}
|
|
3400
|
+
|
|
3424
3401
|
return plain.items.map(item => ChatMessage.parse(item));
|
|
3425
3402
|
}
|
|
3426
3403
|
|
|
@@ -3530,6 +3507,9 @@ class Voicemail {
|
|
|
3530
3507
|
}
|
|
3531
3508
|
|
|
3532
3509
|
static parseMany(plain ) {
|
|
3510
|
+
if (!plain) {
|
|
3511
|
+
return [];
|
|
3512
|
+
}
|
|
3533
3513
|
const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
|
|
3534
3514
|
const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
|
|
3535
3515
|
|
|
@@ -3639,6 +3619,9 @@ class Call {
|
|
|
3639
3619
|
|
|
3640
3620
|
|
|
3641
3621
|
static parseMany(plain ) {
|
|
3622
|
+
if (!plain) {
|
|
3623
|
+
return [];
|
|
3624
|
+
}
|
|
3642
3625
|
return plain.map((plainCall ) => Call.parse(plainCall));
|
|
3643
3626
|
}
|
|
3644
3627
|
|
|
@@ -3811,6 +3794,9 @@ class Recording {
|
|
|
3811
3794
|
|
|
3812
3795
|
|
|
3813
3796
|
static parseMany(recordings = []) {
|
|
3797
|
+
if (!recordings) {
|
|
3798
|
+
return [];
|
|
3799
|
+
}
|
|
3814
3800
|
return recordings.map(item => Recording.parse(item));
|
|
3815
3801
|
}
|
|
3816
3802
|
|
|
@@ -3912,6 +3898,10 @@ class CallLog {
|
|
|
3912
3898
|
}
|
|
3913
3899
|
|
|
3914
3900
|
static parseMany(plain ) {
|
|
3901
|
+
if (!plain || !plain.items) {
|
|
3902
|
+
return [];
|
|
3903
|
+
}
|
|
3904
|
+
|
|
3915
3905
|
return plain.items.map(item => CallLog.parse(item));
|
|
3916
3906
|
}
|
|
3917
3907
|
|
|
@@ -4484,6 +4474,9 @@ class ChatRoom {
|
|
|
4484
4474
|
|
|
4485
4475
|
|
|
4486
4476
|
static parseMany(plain ) {
|
|
4477
|
+
if (!plain || !plain.items) {
|
|
4478
|
+
return [];
|
|
4479
|
+
}
|
|
4487
4480
|
return plain.items.map(item => ChatRoom.parse(item));
|
|
4488
4481
|
}
|
|
4489
4482
|
|
|
@@ -5712,7 +5705,7 @@ class WebRTCClient extends Emitter {
|
|
|
5712
5705
|
}
|
|
5713
5706
|
|
|
5714
5707
|
call(number , enableVideo , audioOnly = false, conference = false) {
|
|
5715
|
-
logger.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
|
|
5708
|
+
logger.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
|
|
5716
5709
|
const inviterOptions = {
|
|
5717
5710
|
sessionDescriptionHandlerOptionsReInvite: {
|
|
5718
5711
|
conference,
|
|
@@ -6788,6 +6781,7 @@ class WebRTCClient extends Emitter {
|
|
|
6788
6781
|
const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
|
|
6789
6782
|
const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
|
|
6790
6783
|
const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
|
|
6784
|
+
const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
|
|
6791
6785
|
|
|
6792
6786
|
logger.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
|
|
6793
6787
|
|
|
@@ -6795,7 +6789,8 @@ class WebRTCClient extends Emitter {
|
|
|
6795
6789
|
constraints: {
|
|
6796
6790
|
// Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
|
|
6797
6791
|
audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
|
|
6798
|
-
video: screenSharing ? (isDesktop
|
|
6792
|
+
video: screenSharing ? (isDesktop
|
|
6793
|
+
? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
|
|
6799
6794
|
: this._getVideoConstraints(enableVideo),
|
|
6800
6795
|
screen: screenSharing,
|
|
6801
6796
|
desktop: isDesktop,
|
|
@@ -7130,11 +7125,14 @@ class WebRTCClient extends Emitter {
|
|
|
7130
7125
|
|
|
7131
7126
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
7132
7127
|
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
|
|
7128
|
+
if (pc) {
|
|
7129
|
+
pc.oniceconnectionstatechange = () => {
|
|
7130
|
+
logger.info('on ice connection state changed', { state: pc.iceConnectionState });
|
|
7131
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
7132
|
+
this.eventEmitter.emit(ON_DISCONNECTED);
|
|
7133
|
+
}
|
|
7134
|
+
};
|
|
7135
|
+
}
|
|
7138
7136
|
|
|
7139
7137
|
if (withEvent) {
|
|
7140
7138
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
@@ -7344,13 +7342,17 @@ class WebRTCClient extends Emitter {
|
|
|
7344
7342
|
const nbStats = this.sessionNetworkStats[sessionId].length;
|
|
7345
7343
|
const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
|
|
7346
7344
|
const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
|
|
7345
|
+
const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
|
|
7347
7346
|
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
7348
7347
|
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
7348
|
+
const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
|
|
7349
7349
|
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
7350
7350
|
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
7351
7351
|
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
7352
|
-
let audioBytesSent = 0;
|
|
7353
|
-
let audioBytesReceived = 0;
|
|
7352
|
+
let audioBytesSent = 0; // content + header
|
|
7353
|
+
let audioBytesReceived = 0; // content + header
|
|
7354
|
+
let audioContentSent = 0; // useful to detect blank call
|
|
7355
|
+
let audioContentReceived = 0;
|
|
7354
7356
|
let videoBytesSent = 0;
|
|
7355
7357
|
let videoBytesReceived = 0;
|
|
7356
7358
|
let transportSent = 0;
|
|
@@ -7359,25 +7361,27 @@ class WebRTCClient extends Emitter {
|
|
|
7359
7361
|
|
|
7360
7362
|
stats.forEach(report => {
|
|
7361
7363
|
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
7362
|
-
audioBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7364
|
+
audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
|
|
7365
|
+
audioContentSent += Number(report.bytesSent);
|
|
7363
7366
|
}
|
|
7364
7367
|
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
7365
|
-
audioBytesSent += report.bytesSent;
|
|
7368
|
+
audioBytesSent += Number(report.bytesSent);
|
|
7366
7369
|
}
|
|
7367
7370
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7368
|
-
videoBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7371
|
+
videoBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
|
|
7369
7372
|
}
|
|
7370
7373
|
if (report.type === 'inbound-rtp' && report.kind === 'audio') {
|
|
7371
|
-
packetsLost += report.packetsLost;
|
|
7372
|
-
networkStats.packetsReceived = report.packetsReceived;
|
|
7373
|
-
audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7374
|
+
packetsLost += Number(report.packetsLost);
|
|
7375
|
+
networkStats.packetsReceived = Number(report.packetsReceived);
|
|
7376
|
+
audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
|
|
7377
|
+
audioContentReceived += Number(report.bytesReceived);
|
|
7374
7378
|
}
|
|
7375
7379
|
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
7376
|
-
videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7380
|
+
videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
|
|
7377
7381
|
}
|
|
7378
7382
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7379
7383
|
if ('framesPerSecond' in report) {
|
|
7380
|
-
networkStats.framesPerSecond = report.framesPerSecond;
|
|
7384
|
+
networkStats.framesPerSecond = Number(report.framesPerSecond);
|
|
7381
7385
|
}
|
|
7382
7386
|
if ('framerateMean' in report) {
|
|
7383
7387
|
// framerateMean is only available in FF
|
|
@@ -7385,24 +7389,31 @@ class WebRTCClient extends Emitter {
|
|
|
7385
7389
|
}
|
|
7386
7390
|
}
|
|
7387
7391
|
if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
|
|
7388
|
-
packetsLost += report.packetsLost;
|
|
7389
|
-
networkStats.roundTripTime = report.roundTripTime;
|
|
7390
|
-
networkStats.jitter = report.jitter;
|
|
7392
|
+
packetsLost += Number(report.packetsLost);
|
|
7393
|
+
networkStats.roundTripTime = Number(report.roundTripTime);
|
|
7394
|
+
networkStats.jitter = Number(report.jitter);
|
|
7391
7395
|
}
|
|
7392
7396
|
if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
|
|
7393
|
-
packetsLost += report.packetsLost;
|
|
7397
|
+
packetsLost += Number(report.packetsLost);
|
|
7394
7398
|
}
|
|
7395
7399
|
if (report.type === 'transport') {
|
|
7396
|
-
transportSent += report.bytesSent;
|
|
7397
|
-
transportReceived += report.bytesReceived;
|
|
7400
|
+
transportSent += Number(report.bytesSent);
|
|
7401
|
+
transportReceived += Number(report.bytesReceived);
|
|
7398
7402
|
}
|
|
7399
7403
|
});
|
|
7400
7404
|
|
|
7401
7405
|
networkStats.packetsLost = packetsLost;
|
|
7406
|
+
|
|
7402
7407
|
networkStats.totalAudioBytesSent = audioBytesSent;
|
|
7403
7408
|
networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
|
|
7404
7409
|
networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
|
|
7405
7410
|
networkStats.audioBytesReceived = audioBytesReceived;
|
|
7411
|
+
|
|
7412
|
+
networkStats.totalAudioContentSent = audioContentSent;
|
|
7413
|
+
networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
|
|
7414
|
+
networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
|
|
7415
|
+
networkStats.audioContentReceived = audioContentReceived;
|
|
7416
|
+
|
|
7406
7417
|
networkStats.totalVideoBytesSent = videoBytesSent;
|
|
7407
7418
|
networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
|
|
7408
7419
|
networkStats.totalVideoBytesReceived = videoBytesReceived;
|
|
@@ -724,10 +724,6 @@ const getSrflxOrRelay = (candidates ) =>
|
|
|
724
724
|
candidates
|
|
725
725
|
.filter(candidate => candidate && (candidate.type === 'srflx' || candidate.type === 'relay'));
|
|
726
726
|
|
|
727
|
-
const areCandidateValid = (candidates ) =>
|
|
728
|
-
getSrflxOrRelay(candidates)
|
|
729
|
-
.length > 0;
|
|
730
|
-
|
|
731
727
|
const getVideoDirection = (sdp ) => {
|
|
732
728
|
const parsedSdp = sdpParser.parse(sdp);
|
|
733
729
|
const videoMedia = parsedSdp.media.find(media => media.type === 'video');
|
|
@@ -780,8 +776,6 @@ const fixSdp = (sdp , candidates , forcePort = true)
|
|
|
780
776
|
/* global RTCSessionDescriptionInit, navigator */
|
|
781
777
|
|
|
782
778
|
const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
|
|
783
|
-
const MAX_WAIT_FOR_ICE_TRIES = 20;
|
|
784
|
-
const WAIT_FOR_ICE_TIMEOUT = 500;
|
|
785
779
|
|
|
786
780
|
// Customized mediaStreamFactory allowing to send screensharing stream directory when upgrading
|
|
787
781
|
const wazoMediaStreamFactory = (constraints ) => {
|
|
@@ -971,38 +965,6 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
971
965
|
this._peerConnection = undefined;
|
|
972
966
|
}
|
|
973
967
|
|
|
974
|
-
async _waitForValidGatheredIce() {
|
|
975
|
-
let tries = 0;
|
|
976
|
-
|
|
977
|
-
while (!areCandidateValid(this.gatheredCandidates) && tries < MAX_WAIT_FOR_ICE_TRIES) {
|
|
978
|
-
wazoLogger.trace('SessionDescriptionHandler._waitForValidGatheredIce, waiting for ice', {
|
|
979
|
-
tries,
|
|
980
|
-
max: MAX_WAIT_FOR_ICE_TRIES,
|
|
981
|
-
});
|
|
982
|
-
|
|
983
|
-
tries++;
|
|
984
|
-
|
|
985
|
-
// eslint-disable-next-line no-await-in-loop
|
|
986
|
-
await new Promise(resolve => setTimeout(resolve, WAIT_FOR_ICE_TIMEOUT));
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
if (tries >= MAX_WAIT_FOR_ICE_TRIES) {
|
|
990
|
-
const errorMsg = 'No valid candidates found, can\'t answer the call';
|
|
991
|
-
const error = new Error(errorMsg);
|
|
992
|
-
wazoLogger.error(errorMsg, { tries, max: MAX_WAIT_FOR_ICE_TRIES });
|
|
993
|
-
|
|
994
|
-
// Emit an error, because sip.js catches the exception and switch to status Terminated.
|
|
995
|
-
this.eventEmitter.emit('error', error);
|
|
996
|
-
|
|
997
|
-
wazoLogger.error('No valid candidates found', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
// eslint-disable-next-line
|
|
1001
|
-
wazoLogger.trace('Found valid candidates', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
|
|
1002
|
-
|
|
1003
|
-
return this.getLocalSessionDescription();
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
968
|
// Overridden to send `inactive` in conference
|
|
1007
969
|
updateDirection(options , isConference = false,
|
|
1008
970
|
audioOnly = false) {
|
|
@@ -2112,6 +2074,9 @@ class Contact {
|
|
|
2112
2074
|
}
|
|
2113
2075
|
|
|
2114
2076
|
static parseMany(response ) {
|
|
2077
|
+
if (!response || !response.results) {
|
|
2078
|
+
return [];
|
|
2079
|
+
}
|
|
2115
2080
|
return response.results.map(r => Contact.parse(r, response.column_types));
|
|
2116
2081
|
}
|
|
2117
2082
|
|
|
@@ -3189,8 +3154,9 @@ class ExternalApp {
|
|
|
3189
3154
|
|
|
3190
3155
|
|
|
3191
3156
|
|
|
3192
|
-
|
|
3157
|
+
|
|
3193
3158
|
|
|
3159
|
+
|
|
3194
3160
|
|
|
3195
3161
|
|
|
3196
3162
|
class Meeting {
|
|
@@ -3201,9 +3167,10 @@ class Meeting {
|
|
|
3201
3167
|
|
|
3202
3168
|
|
|
3203
3169
|
|
|
3204
|
-
|
|
3170
|
+
|
|
3205
3171
|
|
|
3206
3172
|
|
|
3173
|
+
|
|
3207
3174
|
|
|
3208
3175
|
static parse(plain ) {
|
|
3209
3176
|
return new Meeting({
|
|
@@ -3213,12 +3180,16 @@ class Meeting {
|
|
|
3213
3180
|
ownerUuids: plain.owner_uuids,
|
|
3214
3181
|
port: plain.port,
|
|
3215
3182
|
uuid: plain.uuid,
|
|
3216
|
-
|
|
3183
|
+
extension: plain.exten,
|
|
3217
3184
|
persistent: plain.persistent,
|
|
3185
|
+
creationTime: moment(plain.creation_time).toDate(),
|
|
3218
3186
|
});
|
|
3219
3187
|
}
|
|
3220
3188
|
|
|
3221
3189
|
static parseMany(items ) {
|
|
3190
|
+
if (!items) {
|
|
3191
|
+
return [];
|
|
3192
|
+
}
|
|
3222
3193
|
return items.map(plain => Meeting.parse(plain));
|
|
3223
3194
|
}
|
|
3224
3195
|
|
|
@@ -3233,8 +3204,9 @@ class Meeting {
|
|
|
3233
3204
|
ownerUuids,
|
|
3234
3205
|
port,
|
|
3235
3206
|
uri,
|
|
3236
|
-
|
|
3207
|
+
extension,
|
|
3237
3208
|
persistent,
|
|
3209
|
+
creationTime,
|
|
3238
3210
|
} = {}) {
|
|
3239
3211
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
3240
3212
|
this.uri = uri;
|
|
@@ -3242,8 +3214,9 @@ class Meeting {
|
|
|
3242
3214
|
this.ownerUuids = ownerUuids;
|
|
3243
3215
|
this.port = port;
|
|
3244
3216
|
this.uuid = uuid;
|
|
3245
|
-
this.
|
|
3217
|
+
this.extension = extension;
|
|
3246
3218
|
this.persistent = persistent;
|
|
3219
|
+
this.creationTime = creationTime;
|
|
3247
3220
|
|
|
3248
3221
|
// Useful to compare instead of instanceof with minified code
|
|
3249
3222
|
this.type = 'Meeting';
|
|
@@ -3421,6 +3394,10 @@ class ChatMessage {
|
|
|
3421
3394
|
|
|
3422
3395
|
|
|
3423
3396
|
static parseMany(plain ) {
|
|
3397
|
+
if (!plain || !plain.items) {
|
|
3398
|
+
return [];
|
|
3399
|
+
}
|
|
3400
|
+
|
|
3424
3401
|
return plain.items.map(item => ChatMessage.parse(item));
|
|
3425
3402
|
}
|
|
3426
3403
|
|
|
@@ -3530,6 +3507,9 @@ class Voicemail {
|
|
|
3530
3507
|
}
|
|
3531
3508
|
|
|
3532
3509
|
static parseMany(plain ) {
|
|
3510
|
+
if (!plain) {
|
|
3511
|
+
return [];
|
|
3512
|
+
}
|
|
3533
3513
|
const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
|
|
3534
3514
|
const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
|
|
3535
3515
|
|
|
@@ -3639,6 +3619,9 @@ class Call {
|
|
|
3639
3619
|
|
|
3640
3620
|
|
|
3641
3621
|
static parseMany(plain ) {
|
|
3622
|
+
if (!plain) {
|
|
3623
|
+
return [];
|
|
3624
|
+
}
|
|
3642
3625
|
return plain.map((plainCall ) => Call.parse(plainCall));
|
|
3643
3626
|
}
|
|
3644
3627
|
|
|
@@ -3811,6 +3794,9 @@ class Recording {
|
|
|
3811
3794
|
|
|
3812
3795
|
|
|
3813
3796
|
static parseMany(recordings = []) {
|
|
3797
|
+
if (!recordings) {
|
|
3798
|
+
return [];
|
|
3799
|
+
}
|
|
3814
3800
|
return recordings.map(item => Recording.parse(item));
|
|
3815
3801
|
}
|
|
3816
3802
|
|
|
@@ -3912,6 +3898,10 @@ class CallLog {
|
|
|
3912
3898
|
}
|
|
3913
3899
|
|
|
3914
3900
|
static parseMany(plain ) {
|
|
3901
|
+
if (!plain || !plain.items) {
|
|
3902
|
+
return [];
|
|
3903
|
+
}
|
|
3904
|
+
|
|
3915
3905
|
return plain.items.map(item => CallLog.parse(item));
|
|
3916
3906
|
}
|
|
3917
3907
|
|
|
@@ -4484,6 +4474,9 @@ class ChatRoom {
|
|
|
4484
4474
|
|
|
4485
4475
|
|
|
4486
4476
|
static parseMany(plain ) {
|
|
4477
|
+
if (!plain || !plain.items) {
|
|
4478
|
+
return [];
|
|
4479
|
+
}
|
|
4487
4480
|
return plain.items.map(item => ChatRoom.parse(item));
|
|
4488
4481
|
}
|
|
4489
4482
|
|
|
@@ -5712,7 +5705,7 @@ class WebRTCClient extends Emitter {
|
|
|
5712
5705
|
}
|
|
5713
5706
|
|
|
5714
5707
|
call(number , enableVideo , audioOnly = false, conference = false) {
|
|
5715
|
-
logger.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
|
|
5708
|
+
logger.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
|
|
5716
5709
|
const inviterOptions = {
|
|
5717
5710
|
sessionDescriptionHandlerOptionsReInvite: {
|
|
5718
5711
|
conference,
|
|
@@ -6788,6 +6781,7 @@ class WebRTCClient extends Emitter {
|
|
|
6788
6781
|
const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
|
|
6789
6782
|
const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
|
|
6790
6783
|
const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
|
|
6784
|
+
const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
|
|
6791
6785
|
|
|
6792
6786
|
logger.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
|
|
6793
6787
|
|
|
@@ -6795,7 +6789,8 @@ class WebRTCClient extends Emitter {
|
|
|
6795
6789
|
constraints: {
|
|
6796
6790
|
// Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
|
|
6797
6791
|
audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
|
|
6798
|
-
video: screenSharing ? (isDesktop
|
|
6792
|
+
video: screenSharing ? (isDesktop
|
|
6793
|
+
? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
|
|
6799
6794
|
: this._getVideoConstraints(enableVideo),
|
|
6800
6795
|
screen: screenSharing,
|
|
6801
6796
|
desktop: isDesktop,
|
|
@@ -7130,11 +7125,14 @@ class WebRTCClient extends Emitter {
|
|
|
7130
7125
|
|
|
7131
7126
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
7132
7127
|
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
|
|
7128
|
+
if (pc) {
|
|
7129
|
+
pc.oniceconnectionstatechange = () => {
|
|
7130
|
+
logger.info('on ice connection state changed', { state: pc.iceConnectionState });
|
|
7131
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
7132
|
+
this.eventEmitter.emit(ON_DISCONNECTED);
|
|
7133
|
+
}
|
|
7134
|
+
};
|
|
7135
|
+
}
|
|
7138
7136
|
|
|
7139
7137
|
if (withEvent) {
|
|
7140
7138
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
@@ -7344,13 +7342,17 @@ class WebRTCClient extends Emitter {
|
|
|
7344
7342
|
const nbStats = this.sessionNetworkStats[sessionId].length;
|
|
7345
7343
|
const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
|
|
7346
7344
|
const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
|
|
7345
|
+
const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
|
|
7347
7346
|
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
7348
7347
|
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
7348
|
+
const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
|
|
7349
7349
|
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
7350
7350
|
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
7351
7351
|
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
7352
|
-
let audioBytesSent = 0;
|
|
7353
|
-
let audioBytesReceived = 0;
|
|
7352
|
+
let audioBytesSent = 0; // content + header
|
|
7353
|
+
let audioBytesReceived = 0; // content + header
|
|
7354
|
+
let audioContentSent = 0; // useful to detect blank call
|
|
7355
|
+
let audioContentReceived = 0;
|
|
7354
7356
|
let videoBytesSent = 0;
|
|
7355
7357
|
let videoBytesReceived = 0;
|
|
7356
7358
|
let transportSent = 0;
|
|
@@ -7359,25 +7361,27 @@ class WebRTCClient extends Emitter {
|
|
|
7359
7361
|
|
|
7360
7362
|
stats.forEach(report => {
|
|
7361
7363
|
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
7362
|
-
audioBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7364
|
+
audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
|
|
7365
|
+
audioContentSent += Number(report.bytesSent);
|
|
7363
7366
|
}
|
|
7364
7367
|
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
7365
|
-
audioBytesSent += report.bytesSent;
|
|
7368
|
+
audioBytesSent += Number(report.bytesSent);
|
|
7366
7369
|
}
|
|
7367
7370
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7368
|
-
videoBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7371
|
+
videoBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
|
|
7369
7372
|
}
|
|
7370
7373
|
if (report.type === 'inbound-rtp' && report.kind === 'audio') {
|
|
7371
|
-
packetsLost += report.packetsLost;
|
|
7372
|
-
networkStats.packetsReceived = report.packetsReceived;
|
|
7373
|
-
audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7374
|
+
packetsLost += Number(report.packetsLost);
|
|
7375
|
+
networkStats.packetsReceived = Number(report.packetsReceived);
|
|
7376
|
+
audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
|
|
7377
|
+
audioContentReceived += Number(report.bytesReceived);
|
|
7374
7378
|
}
|
|
7375
7379
|
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
7376
|
-
videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7380
|
+
videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
|
|
7377
7381
|
}
|
|
7378
7382
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7379
7383
|
if ('framesPerSecond' in report) {
|
|
7380
|
-
networkStats.framesPerSecond = report.framesPerSecond;
|
|
7384
|
+
networkStats.framesPerSecond = Number(report.framesPerSecond);
|
|
7381
7385
|
}
|
|
7382
7386
|
if ('framerateMean' in report) {
|
|
7383
7387
|
// framerateMean is only available in FF
|
|
@@ -7385,24 +7389,31 @@ class WebRTCClient extends Emitter {
|
|
|
7385
7389
|
}
|
|
7386
7390
|
}
|
|
7387
7391
|
if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
|
|
7388
|
-
packetsLost += report.packetsLost;
|
|
7389
|
-
networkStats.roundTripTime = report.roundTripTime;
|
|
7390
|
-
networkStats.jitter = report.jitter;
|
|
7392
|
+
packetsLost += Number(report.packetsLost);
|
|
7393
|
+
networkStats.roundTripTime = Number(report.roundTripTime);
|
|
7394
|
+
networkStats.jitter = Number(report.jitter);
|
|
7391
7395
|
}
|
|
7392
7396
|
if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
|
|
7393
|
-
packetsLost += report.packetsLost;
|
|
7397
|
+
packetsLost += Number(report.packetsLost);
|
|
7394
7398
|
}
|
|
7395
7399
|
if (report.type === 'transport') {
|
|
7396
|
-
transportSent += report.bytesSent;
|
|
7397
|
-
transportReceived += report.bytesReceived;
|
|
7400
|
+
transportSent += Number(report.bytesSent);
|
|
7401
|
+
transportReceived += Number(report.bytesReceived);
|
|
7398
7402
|
}
|
|
7399
7403
|
});
|
|
7400
7404
|
|
|
7401
7405
|
networkStats.packetsLost = packetsLost;
|
|
7406
|
+
|
|
7402
7407
|
networkStats.totalAudioBytesSent = audioBytesSent;
|
|
7403
7408
|
networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
|
|
7404
7409
|
networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
|
|
7405
7410
|
networkStats.audioBytesReceived = audioBytesReceived;
|
|
7411
|
+
|
|
7412
|
+
networkStats.totalAudioContentSent = audioContentSent;
|
|
7413
|
+
networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
|
|
7414
|
+
networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
|
|
7415
|
+
networkStats.audioContentReceived = audioContentReceived;
|
|
7416
|
+
|
|
7406
7417
|
networkStats.totalVideoBytesSent = videoBytesSent;
|
|
7407
7418
|
networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
|
|
7408
7419
|
networkStats.totalVideoBytesReceived = videoBytesReceived;
|