@wazo/sdk 0.37.16 → 0.37.20
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 +9 -5
- package/esm/__tests__/web-rtc-client.test.js +69 -19
- package/esm/api/agentd.js +1 -1
- package/esm/api/amid.js +1 -1
- package/esm/api/application.js +1 -1
- package/esm/api/auth.js +1 -1
- package/esm/api/call-logd.js +3 -3
- package/esm/api/calld.js +1 -1
- package/esm/api/chatd.js +1 -1
- package/esm/api/confd.js +7 -3
- package/esm/api/ctid-ng.js +1 -1
- package/esm/api/dird.js +1 -1
- package/esm/api/webhookd.js +1 -1
- package/esm/api-client.js +9 -5
- package/esm/checker/Checker.js +69 -19
- package/esm/checker/checks/aor.js +9 -5
- package/esm/checker/checks/api.js +9 -5
- package/esm/checker/checks/index.js +69 -19
- package/esm/checker/checks/wazo-websocket.js +1 -1
- package/esm/checker/checks/webrtc-transport.js +69 -19
- package/esm/checker/checks/webrtc.js +69 -19
- package/esm/domain/AdHocAPIConference.js +9 -5
- package/esm/domain/CallLog.js +2 -2
- package/esm/domain/Features.js +9 -5
- package/esm/domain/Meeting.js +6 -2
- package/esm/domain/Phone/CTIPhone.js +9 -5
- package/esm/domain/Phone/WebRTCPhone.js +9 -2
- package/esm/domain/Recording.js +1 -1
- package/esm/domain/__tests__/CallLog.test.js +2 -2
- package/esm/index.js +77 -19
- package/esm/lib/WazoSessionDescriptionHandler.js +1 -1
- package/esm/service/CallApi.js +9 -5
- package/esm/service/IssueReporter.js +1 -1
- package/esm/service/__tests__/IssueReporter.test.js +1 -1
- package/esm/service/getApiClient.js +9 -5
- package/esm/simple/Auth.js +77 -19
- package/esm/simple/Configuration.js +77 -19
- package/esm/simple/Directory.js +9 -5
- package/esm/simple/Phone.js +77 -19
- package/esm/simple/Websocket.js +1 -1
- package/esm/simple/index.js +77 -19
- package/esm/simple/room/LocalParticipant.js +77 -19
- package/esm/simple/room/Participant.js +77 -19
- package/esm/simple/room/RemoteParticipant.js +77 -19
- package/esm/simple/room/Room.js +77 -19
- package/esm/simple/room/SipRoom.js +77 -19
- package/esm/simple/room/Stream.js +77 -19
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +77 -19
- package/esm/simple/utils.js +77 -19
- package/esm/utils/__tests__/api-requester.test.js +1 -1
- package/esm/utils/api-requester.js +1 -1
- package/esm/web-rtc-client.js +69 -19
- package/esm/websocket-client.js +1 -1
- package/lib/__tests__/api-client.test.js +9 -5
- package/lib/__tests__/web-rtc-client.test.js +69 -19
- package/lib/api/agentd.js +1 -1
- package/lib/api/amid.js +1 -1
- package/lib/api/application.js +1 -1
- package/lib/api/auth.js +1 -1
- package/lib/api/call-logd.js +3 -3
- package/lib/api/calld.js +1 -1
- package/lib/api/chatd.js +1 -1
- package/lib/api/confd.js +7 -3
- package/lib/api/ctid-ng.js +1 -1
- package/lib/api/dird.js +1 -1
- package/lib/api/webhookd.js +1 -1
- package/lib/api-client.js +9 -5
- package/lib/checker/Checker.js +69 -19
- package/lib/checker/checks/aor.js +9 -5
- package/lib/checker/checks/api.js +9 -5
- package/lib/checker/checks/index.js +69 -19
- package/lib/checker/checks/wazo-websocket.js +1 -1
- package/lib/checker/checks/webrtc-transport.js +69 -19
- package/lib/checker/checks/webrtc.js +69 -19
- package/lib/domain/AdHocAPIConference.js +9 -5
- package/lib/domain/CallLog.js +2 -2
- package/lib/domain/Features.js +9 -5
- package/lib/domain/Meeting.js +6 -2
- package/lib/domain/Phone/CTIPhone.js +9 -5
- package/lib/domain/Phone/WebRTCPhone.js +9 -1
- package/lib/domain/Recording.js +1 -1
- package/lib/domain/__tests__/CallLog.test.js +2 -2
- package/lib/index.js +77 -19
- package/lib/lib/WazoSessionDescriptionHandler.js +1 -1
- package/lib/service/CallApi.js +9 -5
- package/lib/service/IssueReporter.js +1 -1
- package/lib/service/__tests__/IssueReporter.test.js +1 -1
- package/lib/service/getApiClient.js +9 -5
- package/lib/simple/Auth.js +77 -19
- package/lib/simple/Configuration.js +77 -19
- package/lib/simple/Directory.js +9 -5
- package/lib/simple/Phone.js +77 -19
- package/lib/simple/Websocket.js +1 -1
- package/lib/simple/index.js +77 -19
- package/lib/simple/room/LocalParticipant.js +77 -19
- package/lib/simple/room/Participant.js +77 -19
- package/lib/simple/room/RemoteParticipant.js +77 -19
- package/lib/simple/room/Room.js +77 -19
- package/lib/simple/room/SipRoom.js +77 -19
- package/lib/simple/room/Stream.js +77 -19
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +77 -19
- package/lib/simple/utils.js +77 -19
- package/lib/utils/__tests__/api-requester.test.js +1 -1
- package/lib/utils/api-requester.js +1 -1
- package/lib/web-rtc-client.js +69 -19
- package/lib/websocket-client.js +1 -1
- package/package.json +2 -2
- package/src/domain/CallLog.js +1 -1
- package/src/domain/Meeting.js +6 -2
- package/src/domain/Phone/WebRTCPhone.js +7 -0
- package/src/domain/Recording.js +1 -1
- package/src/service/IssueReporter.js +1 -1
- package/src/web-rtc-client.js +60 -14
|
@@ -664,7 +664,7 @@ class IssueReporter {
|
|
|
664
664
|
payload._retry = retry + 1;
|
|
665
665
|
}
|
|
666
666
|
|
|
667
|
-
this._sendDebugToGrafana(
|
|
667
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
668
668
|
}, 5000 + retry * 1000);
|
|
669
669
|
});
|
|
670
670
|
}
|
|
@@ -3166,7 +3166,8 @@ class ExternalApp {
|
|
|
3166
3166
|
|
|
3167
3167
|
|
|
3168
3168
|
|
|
3169
|
-
|
|
3169
|
+
|
|
3170
|
+
|
|
3170
3171
|
|
|
3171
3172
|
|
|
3172
3173
|
class Meeting {
|
|
@@ -3178,6 +3179,7 @@ class Meeting {
|
|
|
3178
3179
|
|
|
3179
3180
|
|
|
3180
3181
|
|
|
3182
|
+
|
|
3181
3183
|
|
|
3182
3184
|
|
|
3183
3185
|
static parse(plain ) {
|
|
@@ -3189,6 +3191,7 @@ class Meeting {
|
|
|
3189
3191
|
port: plain.port,
|
|
3190
3192
|
uuid: plain.uuid,
|
|
3191
3193
|
number: plain.number,
|
|
3194
|
+
persistent: plain.persistent,
|
|
3192
3195
|
});
|
|
3193
3196
|
}
|
|
3194
3197
|
|
|
@@ -3196,7 +3199,7 @@ class Meeting {
|
|
|
3196
3199
|
return newFrom(meeting, Meeting);
|
|
3197
3200
|
}
|
|
3198
3201
|
|
|
3199
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
3202
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
3200
3203
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
3201
3204
|
this.uri = uri;
|
|
3202
3205
|
this.name = name;
|
|
@@ -3204,6 +3207,7 @@ class Meeting {
|
|
|
3204
3207
|
this.port = port;
|
|
3205
3208
|
this.uuid = uuid;
|
|
3206
3209
|
this.number = number;
|
|
3210
|
+
this.persistent = persistent;
|
|
3207
3211
|
|
|
3208
3212
|
// Useful to compare instead of instanceof with minified code
|
|
3209
3213
|
this.type = 'Meeting';
|
|
@@ -3767,7 +3771,7 @@ class Recording {
|
|
|
3767
3771
|
|
|
3768
3772
|
|
|
3769
3773
|
|
|
3770
|
-
static parseMany(recordings
|
|
3774
|
+
static parseMany(recordings = []) {
|
|
3771
3775
|
return recordings.map(item => Recording.parse(item));
|
|
3772
3776
|
}
|
|
3773
3777
|
|
|
@@ -3893,7 +3897,7 @@ class CallLog {
|
|
|
3893
3897
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3894
3898
|
start: moment(plain.start).toDate(),
|
|
3895
3899
|
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3896
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3900
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3897
3901
|
});
|
|
3898
3902
|
}
|
|
3899
3903
|
|
|
@@ -5288,6 +5292,7 @@ const ON_REINVITE = 'reinvite';
|
|
|
5288
5292
|
const ON_ERROR = 'onError';
|
|
5289
5293
|
const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
|
|
5290
5294
|
const ON_NETWORK_STATS = 'onNetworkStats';
|
|
5295
|
+
const ON_DISCONNECTED = 'onDisconnected';
|
|
5291
5296
|
class CanceledCallError extends Error {}
|
|
5292
5297
|
|
|
5293
5298
|
const MAX_REGISTER_TRIES = 10;
|
|
@@ -5361,6 +5366,7 @@ class WebRTCClient extends Emitter {
|
|
|
5361
5366
|
|
|
5362
5367
|
|
|
5363
5368
|
|
|
5369
|
+
|
|
5364
5370
|
|
|
5365
5371
|
static isAPrivateIp(ip ) {
|
|
5366
5372
|
const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
|
|
@@ -5426,6 +5432,7 @@ class WebRTCClient extends Emitter {
|
|
|
5426
5432
|
this.ON_ERROR = ON_ERROR;
|
|
5427
5433
|
this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
|
|
5428
5434
|
this.ON_NETWORK_STATS = ON_NETWORK_STATS;
|
|
5435
|
+
this.ON_DISCONNECTED = ON_DISCONNECTED;
|
|
5429
5436
|
}
|
|
5430
5437
|
|
|
5431
5438
|
configureMedia(media ) {
|
|
@@ -6027,7 +6034,7 @@ class WebRTCClient extends Emitter {
|
|
|
6027
6034
|
// We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
|
|
6028
6035
|
const transceivers = pc.getTransceivers();
|
|
6029
6036
|
const transceiverIdx = lastIndexOf(transceivers, transceiver =>
|
|
6030
|
-
transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
|
|
6037
|
+
transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
|
|
6031
6038
|
|
|
6032
6039
|
videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
|
|
6033
6040
|
} else {
|
|
@@ -6273,10 +6280,13 @@ class WebRTCClient extends Emitter {
|
|
|
6273
6280
|
return null;
|
|
6274
6281
|
}
|
|
6275
6282
|
|
|
6276
|
-
// let's update the local value
|
|
6277
|
-
if (this.audio
|
|
6278
|
-
|
|
6279
|
-
|
|
6283
|
+
// let's update the local audio value
|
|
6284
|
+
if (this.audio) {
|
|
6285
|
+
this.audio = {
|
|
6286
|
+
deviceId: {
|
|
6287
|
+
exact: id,
|
|
6288
|
+
},
|
|
6289
|
+
};
|
|
6280
6290
|
}
|
|
6281
6291
|
|
|
6282
6292
|
if (session) {
|
|
@@ -6289,6 +6299,9 @@ class WebRTCClient extends Emitter {
|
|
|
6289
6299
|
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
6290
6300
|
|
|
6291
6301
|
if (sender) {
|
|
6302
|
+
if (sender.track) {
|
|
6303
|
+
audioTrack.enabled = sender.track.enabled;
|
|
6304
|
+
}
|
|
6292
6305
|
sender.replaceTrack(audioTrack);
|
|
6293
6306
|
}
|
|
6294
6307
|
|
|
@@ -6313,7 +6326,7 @@ class WebRTCClient extends Emitter {
|
|
|
6313
6326
|
return null;
|
|
6314
6327
|
}
|
|
6315
6328
|
|
|
6316
|
-
// let's update the local value
|
|
6329
|
+
// let's update the local video value
|
|
6317
6330
|
if (this.video) {
|
|
6318
6331
|
this.video = {
|
|
6319
6332
|
deviceId: {
|
|
@@ -6348,12 +6361,21 @@ class WebRTCClient extends Emitter {
|
|
|
6348
6361
|
return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
|
|
6349
6362
|
const videoTrack = stream.getVideoTracks()[0];
|
|
6350
6363
|
let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
|
|
6364
|
+
let wasTrackEnabled = false;
|
|
6351
6365
|
if (!sender) {
|
|
6352
6366
|
sender = pc && pc.getSenders().find(s => !s.track);
|
|
6353
6367
|
}
|
|
6354
6368
|
|
|
6355
6369
|
if (sender) {
|
|
6356
|
-
|
|
6370
|
+
// No video track means video not enabled
|
|
6371
|
+
wasTrackEnabled = sender.track ? sender.track.enabled : false;
|
|
6372
|
+
videoTrack.enabled = wasTrackEnabled;
|
|
6373
|
+
|
|
6374
|
+
if (!wasTrackEnabled) {
|
|
6375
|
+
videoTrack.stop();
|
|
6376
|
+
}
|
|
6377
|
+
|
|
6378
|
+
sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
|
|
6357
6379
|
}
|
|
6358
6380
|
|
|
6359
6381
|
// let's update the local stream
|
|
@@ -7037,6 +7059,7 @@ class WebRTCClient extends Emitter {
|
|
|
7037
7059
|
|
|
7038
7060
|
this.updateRemoteStream(this.getSipSessionId(session));
|
|
7039
7061
|
|
|
7062
|
+
const pc = session.sessionDescriptionHandler.peerConnection;
|
|
7040
7063
|
const onTrack = (event ) => {
|
|
7041
7064
|
const isAudioOnly = this._isAudioOnly(session);
|
|
7042
7065
|
const { kind, label, readyState, id, muted } = event.track;
|
|
@@ -7056,6 +7079,12 @@ class WebRTCClient extends Emitter {
|
|
|
7056
7079
|
|
|
7057
7080
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
7058
7081
|
|
|
7082
|
+
pc.oniceconnectionstatechange = () => {
|
|
7083
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
7084
|
+
this.eventEmitter.emit(ON_DISCONNECTED);
|
|
7085
|
+
}
|
|
7086
|
+
};
|
|
7087
|
+
|
|
7059
7088
|
if (withEvent) {
|
|
7060
7089
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
7061
7090
|
}
|
|
@@ -7267,25 +7296,33 @@ class WebRTCClient extends Emitter {
|
|
|
7267
7296
|
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
7268
7297
|
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
7269
7298
|
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
7299
|
+
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
7300
|
+
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
7270
7301
|
let audioBytesSent = 0;
|
|
7271
7302
|
let audioBytesReceived = 0;
|
|
7272
7303
|
let videoBytesSent = 0;
|
|
7273
7304
|
let videoBytesReceived = 0;
|
|
7305
|
+
let transportSent = 0;
|
|
7306
|
+
let transportReceived = 0;
|
|
7307
|
+
let packetsLost = 0;
|
|
7274
7308
|
|
|
7275
7309
|
stats.forEach(report => {
|
|
7276
7310
|
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
7311
|
+
audioBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7312
|
+
}
|
|
7313
|
+
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
7277
7314
|
audioBytesSent += report.bytesSent;
|
|
7278
7315
|
}
|
|
7279
7316
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7280
|
-
videoBytesSent += report.bytesSent;
|
|
7317
|
+
videoBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7281
7318
|
}
|
|
7282
7319
|
if (report.type === 'inbound-rtp' && report.kind === 'audio') {
|
|
7283
|
-
|
|
7320
|
+
packetsLost += report.packetsLost;
|
|
7284
7321
|
networkStats.packetsReceived = report.packetsReceived;
|
|
7285
|
-
audioBytesReceived += report.bytesReceived;
|
|
7322
|
+
audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7286
7323
|
}
|
|
7287
7324
|
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
7288
|
-
videoBytesReceived += report.bytesReceived;
|
|
7325
|
+
videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7289
7326
|
}
|
|
7290
7327
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7291
7328
|
if ('framesPerSecond' in report) {
|
|
@@ -7297,19 +7334,32 @@ class WebRTCClient extends Emitter {
|
|
|
7297
7334
|
}
|
|
7298
7335
|
}
|
|
7299
7336
|
if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
|
|
7337
|
+
packetsLost += report.packetsLost;
|
|
7300
7338
|
networkStats.roundTripTime = report.roundTripTime;
|
|
7301
7339
|
networkStats.jitter = report.jitter;
|
|
7302
7340
|
}
|
|
7341
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
|
|
7342
|
+
packetsLost += report.packetsLost;
|
|
7343
|
+
}
|
|
7344
|
+
if (report.type === 'transport') {
|
|
7345
|
+
transportSent += report.bytesSent;
|
|
7346
|
+
transportReceived += report.bytesReceived;
|
|
7347
|
+
}
|
|
7303
7348
|
});
|
|
7304
7349
|
|
|
7350
|
+
networkStats.packetsLost = packetsLost;
|
|
7305
7351
|
networkStats.audioBytesSent = audioBytesSent;
|
|
7306
7352
|
networkStats.audioBytesReceived = audioBytesReceived;
|
|
7307
7353
|
networkStats.videoBytesSent = videoBytesSent;
|
|
7308
7354
|
networkStats.videoBytesReceived = videoBytesReceived;
|
|
7355
|
+
networkStats.transportSent = transportSent;
|
|
7356
|
+
networkStats.transportReceived = transportReceived;
|
|
7357
|
+
|
|
7358
|
+
const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
|
|
7359
|
+
+ (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
|
|
7360
|
+
+ (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
|
|
7309
7361
|
|
|
7310
|
-
networkStats.bandwidth =
|
|
7311
|
-
+ (networkStats.videoBytesSent - lastVideoSent) + (networkStats.audioBytesReceived - lastAudioReceived)
|
|
7312
|
-
+ (networkStats.videoBytesReceived - lastVideoReceived);
|
|
7362
|
+
networkStats.bandwidth = bandwidth;
|
|
7313
7363
|
|
|
7314
7364
|
this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
|
|
7315
7365
|
this.sessionNetworkStats[sessionId].push(networkStats);
|
|
@@ -664,7 +664,7 @@ class IssueReporter {
|
|
|
664
664
|
payload._retry = retry + 1;
|
|
665
665
|
}
|
|
666
666
|
|
|
667
|
-
this._sendDebugToGrafana(
|
|
667
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
668
668
|
}, 5000 + retry * 1000);
|
|
669
669
|
});
|
|
670
670
|
}
|
|
@@ -3166,7 +3166,8 @@ class ExternalApp {
|
|
|
3166
3166
|
|
|
3167
3167
|
|
|
3168
3168
|
|
|
3169
|
-
|
|
3169
|
+
|
|
3170
|
+
|
|
3170
3171
|
|
|
3171
3172
|
|
|
3172
3173
|
class Meeting {
|
|
@@ -3178,6 +3179,7 @@ class Meeting {
|
|
|
3178
3179
|
|
|
3179
3180
|
|
|
3180
3181
|
|
|
3182
|
+
|
|
3181
3183
|
|
|
3182
3184
|
|
|
3183
3185
|
static parse(plain ) {
|
|
@@ -3189,6 +3191,7 @@ class Meeting {
|
|
|
3189
3191
|
port: plain.port,
|
|
3190
3192
|
uuid: plain.uuid,
|
|
3191
3193
|
number: plain.number,
|
|
3194
|
+
persistent: plain.persistent,
|
|
3192
3195
|
});
|
|
3193
3196
|
}
|
|
3194
3197
|
|
|
@@ -3196,7 +3199,7 @@ class Meeting {
|
|
|
3196
3199
|
return newFrom(meeting, Meeting);
|
|
3197
3200
|
}
|
|
3198
3201
|
|
|
3199
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
3202
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
3200
3203
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
3201
3204
|
this.uri = uri;
|
|
3202
3205
|
this.name = name;
|
|
@@ -3204,6 +3207,7 @@ class Meeting {
|
|
|
3204
3207
|
this.port = port;
|
|
3205
3208
|
this.uuid = uuid;
|
|
3206
3209
|
this.number = number;
|
|
3210
|
+
this.persistent = persistent;
|
|
3207
3211
|
|
|
3208
3212
|
// Useful to compare instead of instanceof with minified code
|
|
3209
3213
|
this.type = 'Meeting';
|
|
@@ -3767,7 +3771,7 @@ class Recording {
|
|
|
3767
3771
|
|
|
3768
3772
|
|
|
3769
3773
|
|
|
3770
|
-
static parseMany(recordings
|
|
3774
|
+
static parseMany(recordings = []) {
|
|
3771
3775
|
return recordings.map(item => Recording.parse(item));
|
|
3772
3776
|
}
|
|
3773
3777
|
|
|
@@ -3893,7 +3897,7 @@ class CallLog {
|
|
|
3893
3897
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3894
3898
|
start: moment(plain.start).toDate(),
|
|
3895
3899
|
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3896
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3900
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3897
3901
|
});
|
|
3898
3902
|
}
|
|
3899
3903
|
|
|
@@ -5288,6 +5292,7 @@ const ON_REINVITE = 'reinvite';
|
|
|
5288
5292
|
const ON_ERROR = 'onError';
|
|
5289
5293
|
const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
|
|
5290
5294
|
const ON_NETWORK_STATS = 'onNetworkStats';
|
|
5295
|
+
const ON_DISCONNECTED = 'onDisconnected';
|
|
5291
5296
|
class CanceledCallError extends Error {}
|
|
5292
5297
|
|
|
5293
5298
|
const MAX_REGISTER_TRIES = 10;
|
|
@@ -5361,6 +5366,7 @@ class WebRTCClient extends Emitter {
|
|
|
5361
5366
|
|
|
5362
5367
|
|
|
5363
5368
|
|
|
5369
|
+
|
|
5364
5370
|
|
|
5365
5371
|
static isAPrivateIp(ip ) {
|
|
5366
5372
|
const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
|
|
@@ -5426,6 +5432,7 @@ class WebRTCClient extends Emitter {
|
|
|
5426
5432
|
this.ON_ERROR = ON_ERROR;
|
|
5427
5433
|
this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
|
|
5428
5434
|
this.ON_NETWORK_STATS = ON_NETWORK_STATS;
|
|
5435
|
+
this.ON_DISCONNECTED = ON_DISCONNECTED;
|
|
5429
5436
|
}
|
|
5430
5437
|
|
|
5431
5438
|
configureMedia(media ) {
|
|
@@ -6027,7 +6034,7 @@ class WebRTCClient extends Emitter {
|
|
|
6027
6034
|
// We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
|
|
6028
6035
|
const transceivers = pc.getTransceivers();
|
|
6029
6036
|
const transceiverIdx = lastIndexOf(transceivers, transceiver =>
|
|
6030
|
-
transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
|
|
6037
|
+
transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
|
|
6031
6038
|
|
|
6032
6039
|
videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
|
|
6033
6040
|
} else {
|
|
@@ -6273,10 +6280,13 @@ class WebRTCClient extends Emitter {
|
|
|
6273
6280
|
return null;
|
|
6274
6281
|
}
|
|
6275
6282
|
|
|
6276
|
-
// let's update the local value
|
|
6277
|
-
if (this.audio
|
|
6278
|
-
|
|
6279
|
-
|
|
6283
|
+
// let's update the local audio value
|
|
6284
|
+
if (this.audio) {
|
|
6285
|
+
this.audio = {
|
|
6286
|
+
deviceId: {
|
|
6287
|
+
exact: id,
|
|
6288
|
+
},
|
|
6289
|
+
};
|
|
6280
6290
|
}
|
|
6281
6291
|
|
|
6282
6292
|
if (session) {
|
|
@@ -6289,6 +6299,9 @@ class WebRTCClient extends Emitter {
|
|
|
6289
6299
|
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
6290
6300
|
|
|
6291
6301
|
if (sender) {
|
|
6302
|
+
if (sender.track) {
|
|
6303
|
+
audioTrack.enabled = sender.track.enabled;
|
|
6304
|
+
}
|
|
6292
6305
|
sender.replaceTrack(audioTrack);
|
|
6293
6306
|
}
|
|
6294
6307
|
|
|
@@ -6313,7 +6326,7 @@ class WebRTCClient extends Emitter {
|
|
|
6313
6326
|
return null;
|
|
6314
6327
|
}
|
|
6315
6328
|
|
|
6316
|
-
// let's update the local value
|
|
6329
|
+
// let's update the local video value
|
|
6317
6330
|
if (this.video) {
|
|
6318
6331
|
this.video = {
|
|
6319
6332
|
deviceId: {
|
|
@@ -6348,12 +6361,21 @@ class WebRTCClient extends Emitter {
|
|
|
6348
6361
|
return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
|
|
6349
6362
|
const videoTrack = stream.getVideoTracks()[0];
|
|
6350
6363
|
let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
|
|
6364
|
+
let wasTrackEnabled = false;
|
|
6351
6365
|
if (!sender) {
|
|
6352
6366
|
sender = pc && pc.getSenders().find(s => !s.track);
|
|
6353
6367
|
}
|
|
6354
6368
|
|
|
6355
6369
|
if (sender) {
|
|
6356
|
-
|
|
6370
|
+
// No video track means video not enabled
|
|
6371
|
+
wasTrackEnabled = sender.track ? sender.track.enabled : false;
|
|
6372
|
+
videoTrack.enabled = wasTrackEnabled;
|
|
6373
|
+
|
|
6374
|
+
if (!wasTrackEnabled) {
|
|
6375
|
+
videoTrack.stop();
|
|
6376
|
+
}
|
|
6377
|
+
|
|
6378
|
+
sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
|
|
6357
6379
|
}
|
|
6358
6380
|
|
|
6359
6381
|
// let's update the local stream
|
|
@@ -7037,6 +7059,7 @@ class WebRTCClient extends Emitter {
|
|
|
7037
7059
|
|
|
7038
7060
|
this.updateRemoteStream(this.getSipSessionId(session));
|
|
7039
7061
|
|
|
7062
|
+
const pc = session.sessionDescriptionHandler.peerConnection;
|
|
7040
7063
|
const onTrack = (event ) => {
|
|
7041
7064
|
const isAudioOnly = this._isAudioOnly(session);
|
|
7042
7065
|
const { kind, label, readyState, id, muted } = event.track;
|
|
@@ -7056,6 +7079,12 @@ class WebRTCClient extends Emitter {
|
|
|
7056
7079
|
|
|
7057
7080
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
7058
7081
|
|
|
7082
|
+
pc.oniceconnectionstatechange = () => {
|
|
7083
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
7084
|
+
this.eventEmitter.emit(ON_DISCONNECTED);
|
|
7085
|
+
}
|
|
7086
|
+
};
|
|
7087
|
+
|
|
7059
7088
|
if (withEvent) {
|
|
7060
7089
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
7061
7090
|
}
|
|
@@ -7267,25 +7296,33 @@ class WebRTCClient extends Emitter {
|
|
|
7267
7296
|
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
7268
7297
|
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
7269
7298
|
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
7299
|
+
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
7300
|
+
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
7270
7301
|
let audioBytesSent = 0;
|
|
7271
7302
|
let audioBytesReceived = 0;
|
|
7272
7303
|
let videoBytesSent = 0;
|
|
7273
7304
|
let videoBytesReceived = 0;
|
|
7305
|
+
let transportSent = 0;
|
|
7306
|
+
let transportReceived = 0;
|
|
7307
|
+
let packetsLost = 0;
|
|
7274
7308
|
|
|
7275
7309
|
stats.forEach(report => {
|
|
7276
7310
|
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
7311
|
+
audioBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7312
|
+
}
|
|
7313
|
+
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
7277
7314
|
audioBytesSent += report.bytesSent;
|
|
7278
7315
|
}
|
|
7279
7316
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7280
|
-
videoBytesSent += report.bytesSent;
|
|
7317
|
+
videoBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7281
7318
|
}
|
|
7282
7319
|
if (report.type === 'inbound-rtp' && report.kind === 'audio') {
|
|
7283
|
-
|
|
7320
|
+
packetsLost += report.packetsLost;
|
|
7284
7321
|
networkStats.packetsReceived = report.packetsReceived;
|
|
7285
|
-
audioBytesReceived += report.bytesReceived;
|
|
7322
|
+
audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7286
7323
|
}
|
|
7287
7324
|
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
7288
|
-
videoBytesReceived += report.bytesReceived;
|
|
7325
|
+
videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7289
7326
|
}
|
|
7290
7327
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7291
7328
|
if ('framesPerSecond' in report) {
|
|
@@ -7297,19 +7334,32 @@ class WebRTCClient extends Emitter {
|
|
|
7297
7334
|
}
|
|
7298
7335
|
}
|
|
7299
7336
|
if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
|
|
7337
|
+
packetsLost += report.packetsLost;
|
|
7300
7338
|
networkStats.roundTripTime = report.roundTripTime;
|
|
7301
7339
|
networkStats.jitter = report.jitter;
|
|
7302
7340
|
}
|
|
7341
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
|
|
7342
|
+
packetsLost += report.packetsLost;
|
|
7343
|
+
}
|
|
7344
|
+
if (report.type === 'transport') {
|
|
7345
|
+
transportSent += report.bytesSent;
|
|
7346
|
+
transportReceived += report.bytesReceived;
|
|
7347
|
+
}
|
|
7303
7348
|
});
|
|
7304
7349
|
|
|
7350
|
+
networkStats.packetsLost = packetsLost;
|
|
7305
7351
|
networkStats.audioBytesSent = audioBytesSent;
|
|
7306
7352
|
networkStats.audioBytesReceived = audioBytesReceived;
|
|
7307
7353
|
networkStats.videoBytesSent = videoBytesSent;
|
|
7308
7354
|
networkStats.videoBytesReceived = videoBytesReceived;
|
|
7355
|
+
networkStats.transportSent = transportSent;
|
|
7356
|
+
networkStats.transportReceived = transportReceived;
|
|
7357
|
+
|
|
7358
|
+
const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
|
|
7359
|
+
+ (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
|
|
7360
|
+
+ (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
|
|
7309
7361
|
|
|
7310
|
-
networkStats.bandwidth =
|
|
7311
|
-
+ (networkStats.videoBytesSent - lastVideoSent) + (networkStats.audioBytesReceived - lastAudioReceived)
|
|
7312
|
-
+ (networkStats.videoBytesReceived - lastVideoReceived);
|
|
7362
|
+
networkStats.bandwidth = bandwidth;
|
|
7313
7363
|
|
|
7314
7364
|
this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
|
|
7315
7365
|
this.sessionNetworkStats[sessionId].push(networkStats);
|
|
@@ -599,7 +599,7 @@ class IssueReporter {
|
|
|
599
599
|
payload._retry = retry + 1;
|
|
600
600
|
}
|
|
601
601
|
|
|
602
|
-
this._sendDebugToGrafana(
|
|
602
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
603
603
|
}, 5000 + retry * 1000);
|
|
604
604
|
});
|
|
605
605
|
}
|
|
@@ -2791,7 +2791,8 @@ class ExternalApp {
|
|
|
2791
2791
|
|
|
2792
2792
|
|
|
2793
2793
|
|
|
2794
|
-
|
|
2794
|
+
|
|
2795
|
+
|
|
2795
2796
|
|
|
2796
2797
|
|
|
2797
2798
|
class Meeting {
|
|
@@ -2803,6 +2804,7 @@ class Meeting {
|
|
|
2803
2804
|
|
|
2804
2805
|
|
|
2805
2806
|
|
|
2807
|
+
|
|
2806
2808
|
|
|
2807
2809
|
|
|
2808
2810
|
static parse(plain ) {
|
|
@@ -2814,6 +2816,7 @@ class Meeting {
|
|
|
2814
2816
|
port: plain.port,
|
|
2815
2817
|
uuid: plain.uuid,
|
|
2816
2818
|
number: plain.number,
|
|
2819
|
+
persistent: plain.persistent,
|
|
2817
2820
|
});
|
|
2818
2821
|
}
|
|
2819
2822
|
|
|
@@ -2821,7 +2824,7 @@ class Meeting {
|
|
|
2821
2824
|
return newFrom(meeting, Meeting);
|
|
2822
2825
|
}
|
|
2823
2826
|
|
|
2824
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
2827
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
2825
2828
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2826
2829
|
this.uri = uri;
|
|
2827
2830
|
this.name = name;
|
|
@@ -2829,6 +2832,7 @@ class Meeting {
|
|
|
2829
2832
|
this.port = port;
|
|
2830
2833
|
this.uuid = uuid;
|
|
2831
2834
|
this.number = number;
|
|
2835
|
+
this.persistent = persistent;
|
|
2832
2836
|
|
|
2833
2837
|
// Useful to compare instead of instanceof with minified code
|
|
2834
2838
|
this.type = 'Meeting';
|
|
@@ -3186,7 +3190,7 @@ class Recording {
|
|
|
3186
3190
|
|
|
3187
3191
|
|
|
3188
3192
|
|
|
3189
|
-
static parseMany(recordings
|
|
3193
|
+
static parseMany(recordings = []) {
|
|
3190
3194
|
return recordings.map(item => Recording.parse(item));
|
|
3191
3195
|
}
|
|
3192
3196
|
|
|
@@ -3312,7 +3316,7 @@ class CallLog {
|
|
|
3312
3316
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3313
3317
|
start: moment(plain.start).toDate(),
|
|
3314
3318
|
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3315
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3319
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3316
3320
|
});
|
|
3317
3321
|
}
|
|
3318
3322
|
|
package/esm/domain/CallLog.js
CHANGED
|
@@ -53,7 +53,7 @@ class Recording {
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
|
|
56
|
-
static parseMany(recordings
|
|
56
|
+
static parseMany(recordings = []) {
|
|
57
57
|
return recordings.map(item => Recording.parse(item));
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -179,7 +179,7 @@ class CallLog {
|
|
|
179
179
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
180
180
|
start: moment(plain.start).toDate(),
|
|
181
181
|
end: plain.end ? moment(plain.end).toDate() : null,
|
|
182
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
182
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
183
183
|
});
|
|
184
184
|
}
|
|
185
185
|
|
package/esm/domain/Features.js
CHANGED
|
@@ -382,7 +382,7 @@ class IssueReporter {
|
|
|
382
382
|
payload._retry = retry + 1;
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
-
this._sendDebugToGrafana(
|
|
385
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
386
386
|
}, 5000 + retry * 1000);
|
|
387
387
|
});
|
|
388
388
|
}
|
|
@@ -2585,7 +2585,8 @@ class ExternalApp {
|
|
|
2585
2585
|
|
|
2586
2586
|
|
|
2587
2587
|
|
|
2588
|
-
|
|
2588
|
+
|
|
2589
|
+
|
|
2589
2590
|
|
|
2590
2591
|
|
|
2591
2592
|
class Meeting {
|
|
@@ -2597,6 +2598,7 @@ class Meeting {
|
|
|
2597
2598
|
|
|
2598
2599
|
|
|
2599
2600
|
|
|
2601
|
+
|
|
2600
2602
|
|
|
2601
2603
|
|
|
2602
2604
|
static parse(plain ) {
|
|
@@ -2608,6 +2610,7 @@ class Meeting {
|
|
|
2608
2610
|
port: plain.port,
|
|
2609
2611
|
uuid: plain.uuid,
|
|
2610
2612
|
number: plain.number,
|
|
2613
|
+
persistent: plain.persistent,
|
|
2611
2614
|
});
|
|
2612
2615
|
}
|
|
2613
2616
|
|
|
@@ -2615,7 +2618,7 @@ class Meeting {
|
|
|
2615
2618
|
return newFrom(meeting, Meeting);
|
|
2616
2619
|
}
|
|
2617
2620
|
|
|
2618
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
2621
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
2619
2622
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2620
2623
|
this.uri = uri;
|
|
2621
2624
|
this.name = name;
|
|
@@ -2623,6 +2626,7 @@ class Meeting {
|
|
|
2623
2626
|
this.port = port;
|
|
2624
2627
|
this.uuid = uuid;
|
|
2625
2628
|
this.number = number;
|
|
2629
|
+
this.persistent = persistent;
|
|
2626
2630
|
|
|
2627
2631
|
// Useful to compare instead of instanceof with minified code
|
|
2628
2632
|
this.type = 'Meeting';
|
|
@@ -3186,7 +3190,7 @@ class Recording {
|
|
|
3186
3190
|
|
|
3187
3191
|
|
|
3188
3192
|
|
|
3189
|
-
static parseMany(recordings
|
|
3193
|
+
static parseMany(recordings = []) {
|
|
3190
3194
|
return recordings.map(item => Recording.parse(item));
|
|
3191
3195
|
}
|
|
3192
3196
|
|
|
@@ -3312,7 +3316,7 @@ class CallLog {
|
|
|
3312
3316
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3313
3317
|
start: moment(plain.start).toDate(),
|
|
3314
3318
|
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3315
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3319
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3316
3320
|
});
|
|
3317
3321
|
}
|
|
3318
3322
|
|