@wazo/sdk 0.37.15 → 0.37.19
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 +3 -3
- package/esm/__tests__/api-client.test.js +9 -5
- package/esm/__tests__/web-rtc-client.test.js +117 -23
- 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 +117 -23
- package/esm/checker/checks/aor.js +9 -5
- package/esm/checker/checks/api.js +9 -5
- package/esm/checker/checks/index.js +117 -23
- package/esm/checker/checks/wazo-websocket.js +1 -1
- package/esm/checker/checks/webrtc-transport.js +117 -23
- package/esm/checker/checks/webrtc.js +117 -23
- 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 +125 -23
- 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 +125 -23
- package/esm/simple/Configuration.js +125 -23
- package/esm/simple/Directory.js +9 -5
- package/esm/simple/Phone.js +125 -23
- package/esm/simple/Websocket.js +1 -1
- package/esm/simple/index.js +125 -23
- package/esm/simple/room/LocalParticipant.js +125 -23
- package/esm/simple/room/Participant.js +125 -23
- package/esm/simple/room/RemoteParticipant.js +125 -23
- package/esm/simple/room/Room.js +125 -23
- package/esm/simple/room/SipRoom.js +125 -23
- package/esm/simple/room/Stream.js +125 -23
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +125 -23
- package/esm/simple/utils.js +125 -23
- package/esm/utils/__tests__/api-requester.test.js +1 -1
- package/esm/utils/api-requester.js +1 -1
- package/esm/web-rtc-client.js +117 -23
- package/esm/websocket-client.js +1 -1
- package/lib/__tests__/api-client.test.js +9 -5
- package/lib/__tests__/web-rtc-client.test.js +117 -23
- 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 +117 -23
- package/lib/checker/checks/aor.js +9 -5
- package/lib/checker/checks/api.js +9 -5
- package/lib/checker/checks/index.js +117 -23
- package/lib/checker/checks/wazo-websocket.js +1 -1
- package/lib/checker/checks/webrtc-transport.js +117 -23
- package/lib/checker/checks/webrtc.js +117 -23
- 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 +125 -23
- 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 +125 -23
- package/lib/simple/Configuration.js +125 -23
- package/lib/simple/Directory.js +9 -5
- package/lib/simple/Phone.js +125 -23
- package/lib/simple/Websocket.js +1 -1
- package/lib/simple/index.js +125 -23
- package/lib/simple/room/LocalParticipant.js +125 -23
- package/lib/simple/room/Participant.js +125 -23
- package/lib/simple/room/RemoteParticipant.js +125 -23
- package/lib/simple/room/Room.js +125 -23
- package/lib/simple/room/SipRoom.js +125 -23
- package/lib/simple/room/Stream.js +125 -23
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +125 -23
- package/lib/simple/utils.js +125 -23
- package/lib/utils/__tests__/api-requester.test.js +1 -1
- package/lib/utils/api-requester.js +1 -1
- package/lib/web-rtc-client.js +117 -23
- package/lib/websocket-client.js +1 -1
- package/package.json +1 -1
- 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 +108 -18
|
@@ -673,7 +673,7 @@ class IssueReporter {
|
|
|
673
673
|
payload._retry = retry + 1;
|
|
674
674
|
}
|
|
675
675
|
|
|
676
|
-
this._sendDebugToGrafana(
|
|
676
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
677
677
|
}, 5000 + retry * 1000);
|
|
678
678
|
});
|
|
679
679
|
}
|
|
@@ -3175,7 +3175,8 @@ class ExternalApp {
|
|
|
3175
3175
|
|
|
3176
3176
|
|
|
3177
3177
|
|
|
3178
|
-
|
|
3178
|
+
|
|
3179
|
+
|
|
3179
3180
|
|
|
3180
3181
|
|
|
3181
3182
|
class Meeting {
|
|
@@ -3187,6 +3188,7 @@ class Meeting {
|
|
|
3187
3188
|
|
|
3188
3189
|
|
|
3189
3190
|
|
|
3191
|
+
|
|
3190
3192
|
|
|
3191
3193
|
|
|
3192
3194
|
static parse(plain ) {
|
|
@@ -3198,6 +3200,7 @@ class Meeting {
|
|
|
3198
3200
|
port: plain.port,
|
|
3199
3201
|
uuid: plain.uuid,
|
|
3200
3202
|
number: plain.number,
|
|
3203
|
+
persistent: plain.persistent,
|
|
3201
3204
|
});
|
|
3202
3205
|
}
|
|
3203
3206
|
|
|
@@ -3205,7 +3208,7 @@ class Meeting {
|
|
|
3205
3208
|
return newFrom(meeting, Meeting);
|
|
3206
3209
|
}
|
|
3207
3210
|
|
|
3208
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
3211
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
3209
3212
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
3210
3213
|
this.uri = uri;
|
|
3211
3214
|
this.name = name;
|
|
@@ -3213,6 +3216,7 @@ class Meeting {
|
|
|
3213
3216
|
this.port = port;
|
|
3214
3217
|
this.uuid = uuid;
|
|
3215
3218
|
this.number = number;
|
|
3219
|
+
this.persistent = persistent;
|
|
3216
3220
|
|
|
3217
3221
|
// Useful to compare instead of instanceof with minified code
|
|
3218
3222
|
this.type = 'Meeting';
|
|
@@ -3776,7 +3780,7 @@ class Recording {
|
|
|
3776
3780
|
|
|
3777
3781
|
|
|
3778
3782
|
|
|
3779
|
-
static parseMany(recordings
|
|
3783
|
+
static parseMany(recordings = []) {
|
|
3780
3784
|
return recordings.map(item => Recording.parse(item));
|
|
3781
3785
|
}
|
|
3782
3786
|
|
|
@@ -3902,7 +3906,7 @@ class CallLog {
|
|
|
3902
3906
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3903
3907
|
start: moment__default['default'](plain.start).toDate(),
|
|
3904
3908
|
end: plain.end ? moment__default['default'](plain.end).toDate() : null,
|
|
3905
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3909
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3906
3910
|
});
|
|
3907
3911
|
}
|
|
3908
3912
|
|
|
@@ -5297,6 +5301,7 @@ const ON_REINVITE = 'reinvite';
|
|
|
5297
5301
|
const ON_ERROR = 'onError';
|
|
5298
5302
|
const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
|
|
5299
5303
|
const ON_NETWORK_STATS = 'onNetworkStats';
|
|
5304
|
+
const ON_DISCONNECTED = 'onDisconnected';
|
|
5300
5305
|
class CanceledCallError extends Error {}
|
|
5301
5306
|
|
|
5302
5307
|
const MAX_REGISTER_TRIES = 10;
|
|
@@ -5370,6 +5375,7 @@ class WebRTCClient extends Emitter {
|
|
|
5370
5375
|
|
|
5371
5376
|
|
|
5372
5377
|
|
|
5378
|
+
|
|
5373
5379
|
|
|
5374
5380
|
static isAPrivateIp(ip ) {
|
|
5375
5381
|
const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
|
|
@@ -5435,6 +5441,7 @@ class WebRTCClient extends Emitter {
|
|
|
5435
5441
|
this.ON_ERROR = ON_ERROR;
|
|
5436
5442
|
this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
|
|
5437
5443
|
this.ON_NETWORK_STATS = ON_NETWORK_STATS;
|
|
5444
|
+
this.ON_DISCONNECTED = ON_DISCONNECTED;
|
|
5438
5445
|
}
|
|
5439
5446
|
|
|
5440
5447
|
configureMedia(media ) {
|
|
@@ -6036,7 +6043,7 @@ class WebRTCClient extends Emitter {
|
|
|
6036
6043
|
// We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
|
|
6037
6044
|
const transceivers = pc.getTransceivers();
|
|
6038
6045
|
const transceiverIdx = lastIndexOf(transceivers, transceiver =>
|
|
6039
|
-
transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
|
|
6046
|
+
transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
|
|
6040
6047
|
|
|
6041
6048
|
videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
|
|
6042
6049
|
} else {
|
|
@@ -6282,10 +6289,13 @@ class WebRTCClient extends Emitter {
|
|
|
6282
6289
|
return null;
|
|
6283
6290
|
}
|
|
6284
6291
|
|
|
6285
|
-
// let's update the local value
|
|
6286
|
-
if (this.audio
|
|
6287
|
-
|
|
6288
|
-
|
|
6292
|
+
// let's update the local audio value
|
|
6293
|
+
if (this.audio) {
|
|
6294
|
+
this.audio = {
|
|
6295
|
+
deviceId: {
|
|
6296
|
+
exact: id,
|
|
6297
|
+
},
|
|
6298
|
+
};
|
|
6289
6299
|
}
|
|
6290
6300
|
|
|
6291
6301
|
if (session) {
|
|
@@ -6298,6 +6308,9 @@ class WebRTCClient extends Emitter {
|
|
|
6298
6308
|
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
6299
6309
|
|
|
6300
6310
|
if (sender) {
|
|
6311
|
+
if (sender.track) {
|
|
6312
|
+
audioTrack.enabled = sender.track.enabled;
|
|
6313
|
+
}
|
|
6301
6314
|
sender.replaceTrack(audioTrack);
|
|
6302
6315
|
}
|
|
6303
6316
|
|
|
@@ -6322,7 +6335,7 @@ class WebRTCClient extends Emitter {
|
|
|
6322
6335
|
return null;
|
|
6323
6336
|
}
|
|
6324
6337
|
|
|
6325
|
-
// let's update the local value
|
|
6338
|
+
// let's update the local video value
|
|
6326
6339
|
if (this.video) {
|
|
6327
6340
|
this.video = {
|
|
6328
6341
|
deviceId: {
|
|
@@ -6357,12 +6370,21 @@ class WebRTCClient extends Emitter {
|
|
|
6357
6370
|
return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
|
|
6358
6371
|
const videoTrack = stream.getVideoTracks()[0];
|
|
6359
6372
|
let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
|
|
6373
|
+
let wasTrackEnabled = false;
|
|
6360
6374
|
if (!sender) {
|
|
6361
6375
|
sender = pc && pc.getSenders().find(s => !s.track);
|
|
6362
6376
|
}
|
|
6363
6377
|
|
|
6364
6378
|
if (sender) {
|
|
6365
|
-
|
|
6379
|
+
// No video track means video not enabled
|
|
6380
|
+
wasTrackEnabled = sender.track ? sender.track.enabled : false;
|
|
6381
|
+
videoTrack.enabled = wasTrackEnabled;
|
|
6382
|
+
|
|
6383
|
+
if (!wasTrackEnabled) {
|
|
6384
|
+
videoTrack.stop();
|
|
6385
|
+
}
|
|
6386
|
+
|
|
6387
|
+
sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
|
|
6366
6388
|
}
|
|
6367
6389
|
|
|
6368
6390
|
// let's update the local stream
|
|
@@ -7046,6 +7068,7 @@ class WebRTCClient extends Emitter {
|
|
|
7046
7068
|
|
|
7047
7069
|
this.updateRemoteStream(this.getSipSessionId(session));
|
|
7048
7070
|
|
|
7071
|
+
const pc = session.sessionDescriptionHandler.peerConnection;
|
|
7049
7072
|
const onTrack = (event ) => {
|
|
7050
7073
|
const isAudioOnly = this._isAudioOnly(session);
|
|
7051
7074
|
const { kind, label, readyState, id, muted } = event.track;
|
|
@@ -7065,6 +7088,12 @@ class WebRTCClient extends Emitter {
|
|
|
7065
7088
|
|
|
7066
7089
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
7067
7090
|
|
|
7091
|
+
pc.oniceconnectionstatechange = () => {
|
|
7092
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
7093
|
+
this.eventEmitter.emit(ON_DISCONNECTED);
|
|
7094
|
+
}
|
|
7095
|
+
};
|
|
7096
|
+
|
|
7068
7097
|
if (withEvent) {
|
|
7069
7098
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
7070
7099
|
}
|
|
@@ -7260,24 +7289,89 @@ class WebRTCClient extends Emitter {
|
|
|
7260
7289
|
const session = this.getSipSession(sessionId);
|
|
7261
7290
|
|
|
7262
7291
|
const stats = session ? await this.getStats(session) : null;
|
|
7263
|
-
if (!stats) {
|
|
7292
|
+
if (!stats || !(sessionId in this.sessionNetworkStats)) {
|
|
7264
7293
|
return;
|
|
7265
7294
|
}
|
|
7266
7295
|
|
|
7296
|
+
const networkStats = {
|
|
7297
|
+
audioBytesSent: 0,
|
|
7298
|
+
videoBytesSent: 0,
|
|
7299
|
+
videoBytesReceived: 0,
|
|
7300
|
+
audioBytesReceived: 0,
|
|
7301
|
+
};
|
|
7302
|
+
const nbStats = this.sessionNetworkStats[sessionId].length;
|
|
7303
|
+
const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
|
|
7304
|
+
const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
|
|
7305
|
+
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
7306
|
+
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
7307
|
+
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
7308
|
+
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
7309
|
+
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
7310
|
+
let audioBytesSent = 0;
|
|
7311
|
+
let audioBytesReceived = 0;
|
|
7312
|
+
let videoBytesSent = 0;
|
|
7313
|
+
let videoBytesReceived = 0;
|
|
7314
|
+
let transportSent = 0;
|
|
7315
|
+
let transportReceived = 0;
|
|
7316
|
+
let packetsLost = 0;
|
|
7317
|
+
|
|
7267
7318
|
stats.forEach(report => {
|
|
7268
|
-
if (report.type === '
|
|
7269
|
-
|
|
7270
|
-
|
|
7271
|
-
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7319
|
+
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
7320
|
+
audioBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7321
|
+
}
|
|
7322
|
+
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
7323
|
+
audioBytesSent += report.bytesSent;
|
|
7324
|
+
}
|
|
7325
|
+
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7326
|
+
videoBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7327
|
+
}
|
|
7328
|
+
if (report.type === 'inbound-rtp' && report.kind === 'audio') {
|
|
7329
|
+
packetsLost += report.packetsLost;
|
|
7330
|
+
networkStats.packetsReceived = report.packetsReceived;
|
|
7331
|
+
audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7332
|
+
}
|
|
7333
|
+
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
7334
|
+
videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7335
|
+
}
|
|
7336
|
+
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7337
|
+
if ('framesPerSecond' in report) {
|
|
7338
|
+
networkStats.framesPerSecond = report.framesPerSecond;
|
|
7278
7339
|
}
|
|
7340
|
+
if ('framerateMean' in report) {
|
|
7341
|
+
// framerateMean is only available in FF
|
|
7342
|
+
networkStats.framesPerSecond = Math.round(report.framerateMean);
|
|
7343
|
+
}
|
|
7344
|
+
}
|
|
7345
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
|
|
7346
|
+
packetsLost += report.packetsLost;
|
|
7347
|
+
networkStats.roundTripTime = report.roundTripTime;
|
|
7348
|
+
networkStats.jitter = report.jitter;
|
|
7349
|
+
}
|
|
7350
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
|
|
7351
|
+
packetsLost += report.packetsLost;
|
|
7352
|
+
}
|
|
7353
|
+
if (report.type === 'transport') {
|
|
7354
|
+
transportSent += report.bytesSent;
|
|
7355
|
+
transportReceived += report.bytesReceived;
|
|
7279
7356
|
}
|
|
7280
7357
|
});
|
|
7358
|
+
|
|
7359
|
+
networkStats.packetsLost = packetsLost;
|
|
7360
|
+
networkStats.audioBytesSent = audioBytesSent;
|
|
7361
|
+
networkStats.audioBytesReceived = audioBytesReceived;
|
|
7362
|
+
networkStats.videoBytesSent = videoBytesSent;
|
|
7363
|
+
networkStats.videoBytesReceived = videoBytesReceived;
|
|
7364
|
+
networkStats.transportSent = transportSent;
|
|
7365
|
+
networkStats.transportReceived = transportReceived;
|
|
7366
|
+
|
|
7367
|
+
const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
|
|
7368
|
+
+ (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
|
|
7369
|
+
+ (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
|
|
7370
|
+
|
|
7371
|
+
networkStats.bandwidth = bandwidth;
|
|
7372
|
+
|
|
7373
|
+
this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
|
|
7374
|
+
this.sessionNetworkStats[sessionId].push(networkStats);
|
|
7281
7375
|
}
|
|
7282
7376
|
|
|
7283
7377
|
}
|
|
@@ -673,7 +673,7 @@ class IssueReporter {
|
|
|
673
673
|
payload._retry = retry + 1;
|
|
674
674
|
}
|
|
675
675
|
|
|
676
|
-
this._sendDebugToGrafana(
|
|
676
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
677
677
|
}, 5000 + retry * 1000);
|
|
678
678
|
});
|
|
679
679
|
}
|
|
@@ -3175,7 +3175,8 @@ class ExternalApp {
|
|
|
3175
3175
|
|
|
3176
3176
|
|
|
3177
3177
|
|
|
3178
|
-
|
|
3178
|
+
|
|
3179
|
+
|
|
3179
3180
|
|
|
3180
3181
|
|
|
3181
3182
|
class Meeting {
|
|
@@ -3187,6 +3188,7 @@ class Meeting {
|
|
|
3187
3188
|
|
|
3188
3189
|
|
|
3189
3190
|
|
|
3191
|
+
|
|
3190
3192
|
|
|
3191
3193
|
|
|
3192
3194
|
static parse(plain ) {
|
|
@@ -3198,6 +3200,7 @@ class Meeting {
|
|
|
3198
3200
|
port: plain.port,
|
|
3199
3201
|
uuid: plain.uuid,
|
|
3200
3202
|
number: plain.number,
|
|
3203
|
+
persistent: plain.persistent,
|
|
3201
3204
|
});
|
|
3202
3205
|
}
|
|
3203
3206
|
|
|
@@ -3205,7 +3208,7 @@ class Meeting {
|
|
|
3205
3208
|
return newFrom(meeting, Meeting);
|
|
3206
3209
|
}
|
|
3207
3210
|
|
|
3208
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
3211
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
3209
3212
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
3210
3213
|
this.uri = uri;
|
|
3211
3214
|
this.name = name;
|
|
@@ -3213,6 +3216,7 @@ class Meeting {
|
|
|
3213
3216
|
this.port = port;
|
|
3214
3217
|
this.uuid = uuid;
|
|
3215
3218
|
this.number = number;
|
|
3219
|
+
this.persistent = persistent;
|
|
3216
3220
|
|
|
3217
3221
|
// Useful to compare instead of instanceof with minified code
|
|
3218
3222
|
this.type = 'Meeting';
|
|
@@ -3776,7 +3780,7 @@ class Recording {
|
|
|
3776
3780
|
|
|
3777
3781
|
|
|
3778
3782
|
|
|
3779
|
-
static parseMany(recordings
|
|
3783
|
+
static parseMany(recordings = []) {
|
|
3780
3784
|
return recordings.map(item => Recording.parse(item));
|
|
3781
3785
|
}
|
|
3782
3786
|
|
|
@@ -3902,7 +3906,7 @@ class CallLog {
|
|
|
3902
3906
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3903
3907
|
start: moment__default['default'](plain.start).toDate(),
|
|
3904
3908
|
end: plain.end ? moment__default['default'](plain.end).toDate() : null,
|
|
3905
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3909
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3906
3910
|
});
|
|
3907
3911
|
}
|
|
3908
3912
|
|
|
@@ -5297,6 +5301,7 @@ const ON_REINVITE = 'reinvite';
|
|
|
5297
5301
|
const ON_ERROR = 'onError';
|
|
5298
5302
|
const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
|
|
5299
5303
|
const ON_NETWORK_STATS = 'onNetworkStats';
|
|
5304
|
+
const ON_DISCONNECTED = 'onDisconnected';
|
|
5300
5305
|
class CanceledCallError extends Error {}
|
|
5301
5306
|
|
|
5302
5307
|
const MAX_REGISTER_TRIES = 10;
|
|
@@ -5370,6 +5375,7 @@ class WebRTCClient extends Emitter {
|
|
|
5370
5375
|
|
|
5371
5376
|
|
|
5372
5377
|
|
|
5378
|
+
|
|
5373
5379
|
|
|
5374
5380
|
static isAPrivateIp(ip ) {
|
|
5375
5381
|
const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
|
|
@@ -5435,6 +5441,7 @@ class WebRTCClient extends Emitter {
|
|
|
5435
5441
|
this.ON_ERROR = ON_ERROR;
|
|
5436
5442
|
this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
|
|
5437
5443
|
this.ON_NETWORK_STATS = ON_NETWORK_STATS;
|
|
5444
|
+
this.ON_DISCONNECTED = ON_DISCONNECTED;
|
|
5438
5445
|
}
|
|
5439
5446
|
|
|
5440
5447
|
configureMedia(media ) {
|
|
@@ -6036,7 +6043,7 @@ class WebRTCClient extends Emitter {
|
|
|
6036
6043
|
// We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
|
|
6037
6044
|
const transceivers = pc.getTransceivers();
|
|
6038
6045
|
const transceiverIdx = lastIndexOf(transceivers, transceiver =>
|
|
6039
|
-
transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
|
|
6046
|
+
transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
|
|
6040
6047
|
|
|
6041
6048
|
videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
|
|
6042
6049
|
} else {
|
|
@@ -6282,10 +6289,13 @@ class WebRTCClient extends Emitter {
|
|
|
6282
6289
|
return null;
|
|
6283
6290
|
}
|
|
6284
6291
|
|
|
6285
|
-
// let's update the local value
|
|
6286
|
-
if (this.audio
|
|
6287
|
-
|
|
6288
|
-
|
|
6292
|
+
// let's update the local audio value
|
|
6293
|
+
if (this.audio) {
|
|
6294
|
+
this.audio = {
|
|
6295
|
+
deviceId: {
|
|
6296
|
+
exact: id,
|
|
6297
|
+
},
|
|
6298
|
+
};
|
|
6289
6299
|
}
|
|
6290
6300
|
|
|
6291
6301
|
if (session) {
|
|
@@ -6298,6 +6308,9 @@ class WebRTCClient extends Emitter {
|
|
|
6298
6308
|
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
6299
6309
|
|
|
6300
6310
|
if (sender) {
|
|
6311
|
+
if (sender.track) {
|
|
6312
|
+
audioTrack.enabled = sender.track.enabled;
|
|
6313
|
+
}
|
|
6301
6314
|
sender.replaceTrack(audioTrack);
|
|
6302
6315
|
}
|
|
6303
6316
|
|
|
@@ -6322,7 +6335,7 @@ class WebRTCClient extends Emitter {
|
|
|
6322
6335
|
return null;
|
|
6323
6336
|
}
|
|
6324
6337
|
|
|
6325
|
-
// let's update the local value
|
|
6338
|
+
// let's update the local video value
|
|
6326
6339
|
if (this.video) {
|
|
6327
6340
|
this.video = {
|
|
6328
6341
|
deviceId: {
|
|
@@ -6357,12 +6370,21 @@ class WebRTCClient extends Emitter {
|
|
|
6357
6370
|
return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
|
|
6358
6371
|
const videoTrack = stream.getVideoTracks()[0];
|
|
6359
6372
|
let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
|
|
6373
|
+
let wasTrackEnabled = false;
|
|
6360
6374
|
if (!sender) {
|
|
6361
6375
|
sender = pc && pc.getSenders().find(s => !s.track);
|
|
6362
6376
|
}
|
|
6363
6377
|
|
|
6364
6378
|
if (sender) {
|
|
6365
|
-
|
|
6379
|
+
// No video track means video not enabled
|
|
6380
|
+
wasTrackEnabled = sender.track ? sender.track.enabled : false;
|
|
6381
|
+
videoTrack.enabled = wasTrackEnabled;
|
|
6382
|
+
|
|
6383
|
+
if (!wasTrackEnabled) {
|
|
6384
|
+
videoTrack.stop();
|
|
6385
|
+
}
|
|
6386
|
+
|
|
6387
|
+
sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
|
|
6366
6388
|
}
|
|
6367
6389
|
|
|
6368
6390
|
// let's update the local stream
|
|
@@ -7046,6 +7068,7 @@ class WebRTCClient extends Emitter {
|
|
|
7046
7068
|
|
|
7047
7069
|
this.updateRemoteStream(this.getSipSessionId(session));
|
|
7048
7070
|
|
|
7071
|
+
const pc = session.sessionDescriptionHandler.peerConnection;
|
|
7049
7072
|
const onTrack = (event ) => {
|
|
7050
7073
|
const isAudioOnly = this._isAudioOnly(session);
|
|
7051
7074
|
const { kind, label, readyState, id, muted } = event.track;
|
|
@@ -7065,6 +7088,12 @@ class WebRTCClient extends Emitter {
|
|
|
7065
7088
|
|
|
7066
7089
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
7067
7090
|
|
|
7091
|
+
pc.oniceconnectionstatechange = () => {
|
|
7092
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
7093
|
+
this.eventEmitter.emit(ON_DISCONNECTED);
|
|
7094
|
+
}
|
|
7095
|
+
};
|
|
7096
|
+
|
|
7068
7097
|
if (withEvent) {
|
|
7069
7098
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
7070
7099
|
}
|
|
@@ -7260,24 +7289,89 @@ class WebRTCClient extends Emitter {
|
|
|
7260
7289
|
const session = this.getSipSession(sessionId);
|
|
7261
7290
|
|
|
7262
7291
|
const stats = session ? await this.getStats(session) : null;
|
|
7263
|
-
if (!stats) {
|
|
7292
|
+
if (!stats || !(sessionId in this.sessionNetworkStats)) {
|
|
7264
7293
|
return;
|
|
7265
7294
|
}
|
|
7266
7295
|
|
|
7296
|
+
const networkStats = {
|
|
7297
|
+
audioBytesSent: 0,
|
|
7298
|
+
videoBytesSent: 0,
|
|
7299
|
+
videoBytesReceived: 0,
|
|
7300
|
+
audioBytesReceived: 0,
|
|
7301
|
+
};
|
|
7302
|
+
const nbStats = this.sessionNetworkStats[sessionId].length;
|
|
7303
|
+
const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
|
|
7304
|
+
const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
|
|
7305
|
+
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
7306
|
+
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
7307
|
+
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
7308
|
+
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
7309
|
+
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
7310
|
+
let audioBytesSent = 0;
|
|
7311
|
+
let audioBytesReceived = 0;
|
|
7312
|
+
let videoBytesSent = 0;
|
|
7313
|
+
let videoBytesReceived = 0;
|
|
7314
|
+
let transportSent = 0;
|
|
7315
|
+
let transportReceived = 0;
|
|
7316
|
+
let packetsLost = 0;
|
|
7317
|
+
|
|
7267
7318
|
stats.forEach(report => {
|
|
7268
|
-
if (report.type === '
|
|
7269
|
-
|
|
7270
|
-
|
|
7271
|
-
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7319
|
+
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
7320
|
+
audioBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7321
|
+
}
|
|
7322
|
+
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
7323
|
+
audioBytesSent += report.bytesSent;
|
|
7324
|
+
}
|
|
7325
|
+
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7326
|
+
videoBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7327
|
+
}
|
|
7328
|
+
if (report.type === 'inbound-rtp' && report.kind === 'audio') {
|
|
7329
|
+
packetsLost += report.packetsLost;
|
|
7330
|
+
networkStats.packetsReceived = report.packetsReceived;
|
|
7331
|
+
audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7332
|
+
}
|
|
7333
|
+
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
7334
|
+
videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7335
|
+
}
|
|
7336
|
+
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7337
|
+
if ('framesPerSecond' in report) {
|
|
7338
|
+
networkStats.framesPerSecond = report.framesPerSecond;
|
|
7278
7339
|
}
|
|
7340
|
+
if ('framerateMean' in report) {
|
|
7341
|
+
// framerateMean is only available in FF
|
|
7342
|
+
networkStats.framesPerSecond = Math.round(report.framerateMean);
|
|
7343
|
+
}
|
|
7344
|
+
}
|
|
7345
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
|
|
7346
|
+
packetsLost += report.packetsLost;
|
|
7347
|
+
networkStats.roundTripTime = report.roundTripTime;
|
|
7348
|
+
networkStats.jitter = report.jitter;
|
|
7349
|
+
}
|
|
7350
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
|
|
7351
|
+
packetsLost += report.packetsLost;
|
|
7352
|
+
}
|
|
7353
|
+
if (report.type === 'transport') {
|
|
7354
|
+
transportSent += report.bytesSent;
|
|
7355
|
+
transportReceived += report.bytesReceived;
|
|
7279
7356
|
}
|
|
7280
7357
|
});
|
|
7358
|
+
|
|
7359
|
+
networkStats.packetsLost = packetsLost;
|
|
7360
|
+
networkStats.audioBytesSent = audioBytesSent;
|
|
7361
|
+
networkStats.audioBytesReceived = audioBytesReceived;
|
|
7362
|
+
networkStats.videoBytesSent = videoBytesSent;
|
|
7363
|
+
networkStats.videoBytesReceived = videoBytesReceived;
|
|
7364
|
+
networkStats.transportSent = transportSent;
|
|
7365
|
+
networkStats.transportReceived = transportReceived;
|
|
7366
|
+
|
|
7367
|
+
const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
|
|
7368
|
+
+ (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
|
|
7369
|
+
+ (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
|
|
7370
|
+
|
|
7371
|
+
networkStats.bandwidth = bandwidth;
|
|
7372
|
+
|
|
7373
|
+
this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
|
|
7374
|
+
this.sessionNetworkStats[sessionId].push(networkStats);
|
|
7281
7375
|
}
|
|
7282
7376
|
|
|
7283
7377
|
}
|
|
@@ -605,7 +605,7 @@ class IssueReporter {
|
|
|
605
605
|
payload._retry = retry + 1;
|
|
606
606
|
}
|
|
607
607
|
|
|
608
|
-
this._sendDebugToGrafana(
|
|
608
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
609
609
|
}, 5000 + retry * 1000);
|
|
610
610
|
});
|
|
611
611
|
}
|
|
@@ -2797,7 +2797,8 @@ class ExternalApp {
|
|
|
2797
2797
|
|
|
2798
2798
|
|
|
2799
2799
|
|
|
2800
|
-
|
|
2800
|
+
|
|
2801
|
+
|
|
2801
2802
|
|
|
2802
2803
|
|
|
2803
2804
|
class Meeting {
|
|
@@ -2809,6 +2810,7 @@ class Meeting {
|
|
|
2809
2810
|
|
|
2810
2811
|
|
|
2811
2812
|
|
|
2813
|
+
|
|
2812
2814
|
|
|
2813
2815
|
|
|
2814
2816
|
static parse(plain ) {
|
|
@@ -2820,6 +2822,7 @@ class Meeting {
|
|
|
2820
2822
|
port: plain.port,
|
|
2821
2823
|
uuid: plain.uuid,
|
|
2822
2824
|
number: plain.number,
|
|
2825
|
+
persistent: plain.persistent,
|
|
2823
2826
|
});
|
|
2824
2827
|
}
|
|
2825
2828
|
|
|
@@ -2827,7 +2830,7 @@ class Meeting {
|
|
|
2827
2830
|
return newFrom(meeting, Meeting);
|
|
2828
2831
|
}
|
|
2829
2832
|
|
|
2830
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
2833
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
2831
2834
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2832
2835
|
this.uri = uri;
|
|
2833
2836
|
this.name = name;
|
|
@@ -2835,6 +2838,7 @@ class Meeting {
|
|
|
2835
2838
|
this.port = port;
|
|
2836
2839
|
this.uuid = uuid;
|
|
2837
2840
|
this.number = number;
|
|
2841
|
+
this.persistent = persistent;
|
|
2838
2842
|
|
|
2839
2843
|
// Useful to compare instead of instanceof with minified code
|
|
2840
2844
|
this.type = 'Meeting';
|
|
@@ -3192,7 +3196,7 @@ class Recording {
|
|
|
3192
3196
|
|
|
3193
3197
|
|
|
3194
3198
|
|
|
3195
|
-
static parseMany(recordings
|
|
3199
|
+
static parseMany(recordings = []) {
|
|
3196
3200
|
return recordings.map(item => Recording.parse(item));
|
|
3197
3201
|
}
|
|
3198
3202
|
|
|
@@ -3318,7 +3322,7 @@ class CallLog {
|
|
|
3318
3322
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3319
3323
|
start: moment__default['default'](plain.start).toDate(),
|
|
3320
3324
|
end: plain.end ? moment__default['default'](plain.end).toDate() : null,
|
|
3321
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3325
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3322
3326
|
});
|
|
3323
3327
|
}
|
|
3324
3328
|
|
package/lib/domain/CallLog.js
CHANGED
|
@@ -59,7 +59,7 @@ class Recording {
|
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
|
|
62
|
-
static parseMany(recordings
|
|
62
|
+
static parseMany(recordings = []) {
|
|
63
63
|
return recordings.map(item => Recording.parse(item));
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -185,7 +185,7 @@ class CallLog {
|
|
|
185
185
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
186
186
|
start: moment__default['default'](plain.start).toDate(),
|
|
187
187
|
end: plain.end ? moment__default['default'](plain.end).toDate() : null,
|
|
188
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
188
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
189
189
|
});
|
|
190
190
|
}
|
|
191
191
|
|