@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.
Files changed (114) hide show
  1. package/dist/wazo-sdk.js +5 -5
  2. package/esm/__tests__/api-client.test.js +9 -5
  3. package/esm/__tests__/web-rtc-client.test.js +69 -19
  4. package/esm/api/agentd.js +1 -1
  5. package/esm/api/amid.js +1 -1
  6. package/esm/api/application.js +1 -1
  7. package/esm/api/auth.js +1 -1
  8. package/esm/api/call-logd.js +3 -3
  9. package/esm/api/calld.js +1 -1
  10. package/esm/api/chatd.js +1 -1
  11. package/esm/api/confd.js +7 -3
  12. package/esm/api/ctid-ng.js +1 -1
  13. package/esm/api/dird.js +1 -1
  14. package/esm/api/webhookd.js +1 -1
  15. package/esm/api-client.js +9 -5
  16. package/esm/checker/Checker.js +69 -19
  17. package/esm/checker/checks/aor.js +9 -5
  18. package/esm/checker/checks/api.js +9 -5
  19. package/esm/checker/checks/index.js +69 -19
  20. package/esm/checker/checks/wazo-websocket.js +1 -1
  21. package/esm/checker/checks/webrtc-transport.js +69 -19
  22. package/esm/checker/checks/webrtc.js +69 -19
  23. package/esm/domain/AdHocAPIConference.js +9 -5
  24. package/esm/domain/CallLog.js +2 -2
  25. package/esm/domain/Features.js +9 -5
  26. package/esm/domain/Meeting.js +6 -2
  27. package/esm/domain/Phone/CTIPhone.js +9 -5
  28. package/esm/domain/Phone/WebRTCPhone.js +9 -2
  29. package/esm/domain/Recording.js +1 -1
  30. package/esm/domain/__tests__/CallLog.test.js +2 -2
  31. package/esm/index.js +77 -19
  32. package/esm/lib/WazoSessionDescriptionHandler.js +1 -1
  33. package/esm/service/CallApi.js +9 -5
  34. package/esm/service/IssueReporter.js +1 -1
  35. package/esm/service/__tests__/IssueReporter.test.js +1 -1
  36. package/esm/service/getApiClient.js +9 -5
  37. package/esm/simple/Auth.js +77 -19
  38. package/esm/simple/Configuration.js +77 -19
  39. package/esm/simple/Directory.js +9 -5
  40. package/esm/simple/Phone.js +77 -19
  41. package/esm/simple/Websocket.js +1 -1
  42. package/esm/simple/index.js +77 -19
  43. package/esm/simple/room/LocalParticipant.js +77 -19
  44. package/esm/simple/room/Participant.js +77 -19
  45. package/esm/simple/room/RemoteParticipant.js +77 -19
  46. package/esm/simple/room/Room.js +77 -19
  47. package/esm/simple/room/SipRoom.js +77 -19
  48. package/esm/simple/room/Stream.js +77 -19
  49. package/esm/simple/room/__tests__/RemoteParticipant.test.js +77 -19
  50. package/esm/simple/utils.js +77 -19
  51. package/esm/utils/__tests__/api-requester.test.js +1 -1
  52. package/esm/utils/api-requester.js +1 -1
  53. package/esm/web-rtc-client.js +69 -19
  54. package/esm/websocket-client.js +1 -1
  55. package/lib/__tests__/api-client.test.js +9 -5
  56. package/lib/__tests__/web-rtc-client.test.js +69 -19
  57. package/lib/api/agentd.js +1 -1
  58. package/lib/api/amid.js +1 -1
  59. package/lib/api/application.js +1 -1
  60. package/lib/api/auth.js +1 -1
  61. package/lib/api/call-logd.js +3 -3
  62. package/lib/api/calld.js +1 -1
  63. package/lib/api/chatd.js +1 -1
  64. package/lib/api/confd.js +7 -3
  65. package/lib/api/ctid-ng.js +1 -1
  66. package/lib/api/dird.js +1 -1
  67. package/lib/api/webhookd.js +1 -1
  68. package/lib/api-client.js +9 -5
  69. package/lib/checker/Checker.js +69 -19
  70. package/lib/checker/checks/aor.js +9 -5
  71. package/lib/checker/checks/api.js +9 -5
  72. package/lib/checker/checks/index.js +69 -19
  73. package/lib/checker/checks/wazo-websocket.js +1 -1
  74. package/lib/checker/checks/webrtc-transport.js +69 -19
  75. package/lib/checker/checks/webrtc.js +69 -19
  76. package/lib/domain/AdHocAPIConference.js +9 -5
  77. package/lib/domain/CallLog.js +2 -2
  78. package/lib/domain/Features.js +9 -5
  79. package/lib/domain/Meeting.js +6 -2
  80. package/lib/domain/Phone/CTIPhone.js +9 -5
  81. package/lib/domain/Phone/WebRTCPhone.js +9 -1
  82. package/lib/domain/Recording.js +1 -1
  83. package/lib/domain/__tests__/CallLog.test.js +2 -2
  84. package/lib/index.js +77 -19
  85. package/lib/lib/WazoSessionDescriptionHandler.js +1 -1
  86. package/lib/service/CallApi.js +9 -5
  87. package/lib/service/IssueReporter.js +1 -1
  88. package/lib/service/__tests__/IssueReporter.test.js +1 -1
  89. package/lib/service/getApiClient.js +9 -5
  90. package/lib/simple/Auth.js +77 -19
  91. package/lib/simple/Configuration.js +77 -19
  92. package/lib/simple/Directory.js +9 -5
  93. package/lib/simple/Phone.js +77 -19
  94. package/lib/simple/Websocket.js +1 -1
  95. package/lib/simple/index.js +77 -19
  96. package/lib/simple/room/LocalParticipant.js +77 -19
  97. package/lib/simple/room/Participant.js +77 -19
  98. package/lib/simple/room/RemoteParticipant.js +77 -19
  99. package/lib/simple/room/Room.js +77 -19
  100. package/lib/simple/room/SipRoom.js +77 -19
  101. package/lib/simple/room/Stream.js +77 -19
  102. package/lib/simple/room/__tests__/RemoteParticipant.test.js +77 -19
  103. package/lib/simple/utils.js +77 -19
  104. package/lib/utils/__tests__/api-requester.test.js +1 -1
  105. package/lib/utils/api-requester.js +1 -1
  106. package/lib/web-rtc-client.js +69 -19
  107. package/lib/websocket-client.js +1 -1
  108. package/package.json +2 -2
  109. package/src/domain/CallLog.js +1 -1
  110. package/src/domain/Meeting.js +6 -2
  111. package/src/domain/Phone/WebRTCPhone.js +7 -0
  112. package/src/domain/Recording.js +1 -1
  113. package/src/service/IssueReporter.js +1 -1
  114. package/src/web-rtc-client.js +60 -14
@@ -973,7 +973,7 @@ class IssueReporter {
973
973
  payload._retry = retry + 1;
974
974
  }
975
975
 
976
- this._sendDebugToGrafana(body, retry + 1);
976
+ this._sendDebugToGrafana(payload, retry + 1);
977
977
  }, 5000 + retry * 1000);
978
978
  });
979
979
  }
@@ -3165,7 +3165,8 @@ class ExternalApp {
3165
3165
 
3166
3166
 
3167
3167
 
3168
-
3168
+
3169
+
3169
3170
 
3170
3171
 
3171
3172
  class Meeting {
@@ -3177,6 +3178,7 @@ class Meeting {
3177
3178
 
3178
3179
 
3179
3180
 
3181
+
3180
3182
 
3181
3183
 
3182
3184
  static parse(plain ) {
@@ -3188,6 +3190,7 @@ class Meeting {
3188
3190
  port: plain.port,
3189
3191
  uuid: plain.uuid,
3190
3192
  number: plain.number,
3193
+ persistent: plain.persistent,
3191
3194
  });
3192
3195
  }
3193
3196
 
@@ -3195,7 +3198,7 @@ class Meeting {
3195
3198
  return newFrom(meeting, Meeting);
3196
3199
  }
3197
3200
 
3198
- constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
3201
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
3199
3202
  this.guestSipAuthorization = guestSipAuthorization;
3200
3203
  this.uri = uri;
3201
3204
  this.name = name;
@@ -3203,6 +3206,7 @@ class Meeting {
3203
3206
  this.port = port;
3204
3207
  this.uuid = uuid;
3205
3208
  this.number = number;
3209
+ this.persistent = persistent;
3206
3210
 
3207
3211
  // Useful to compare instead of instanceof with minified code
3208
3212
  this.type = 'Meeting';
@@ -3586,7 +3590,7 @@ class Recording {
3586
3590
 
3587
3591
 
3588
3592
 
3589
- static parseMany(recordings ) {
3593
+ static parseMany(recordings = []) {
3590
3594
  return recordings.map(item => Recording.parse(item));
3591
3595
  }
3592
3596
 
@@ -3712,7 +3716,7 @@ class CallLog {
3712
3716
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3713
3717
  start: moment__default['default'](plain.start).toDate(),
3714
3718
  end: plain.end ? moment__default['default'](plain.end).toDate() : null,
3715
- recordings: Recording.parseMany(plain.recordings),
3719
+ recordings: Recording.parseMany(plain.recordings || []),
3716
3720
  });
3717
3721
  }
3718
3722
 
@@ -6293,6 +6297,7 @@ const ON_REINVITE$1 = 'reinvite';
6293
6297
  const ON_ERROR = 'onError';
6294
6298
  const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
6295
6299
  const ON_NETWORK_STATS$1 = 'onNetworkStats';
6300
+ const ON_DISCONNECTED$1 = 'onDisconnected';
6296
6301
 
6297
6302
  const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
6298
6303
  const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
@@ -6369,6 +6374,7 @@ class WebRTCClient extends Emitter {
6369
6374
 
6370
6375
 
6371
6376
 
6377
+
6372
6378
 
6373
6379
  static isAPrivateIp(ip ) {
6374
6380
  const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
@@ -6434,6 +6440,7 @@ class WebRTCClient extends Emitter {
6434
6440
  this.ON_ERROR = ON_ERROR;
6435
6441
  this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
6436
6442
  this.ON_NETWORK_STATS = ON_NETWORK_STATS$1;
6443
+ this.ON_DISCONNECTED = ON_DISCONNECTED$1;
6437
6444
  }
6438
6445
 
6439
6446
  configureMedia(media ) {
@@ -7035,7 +7042,7 @@ class WebRTCClient extends Emitter {
7035
7042
  // We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
7036
7043
  const transceivers = pc.getTransceivers();
7037
7044
  const transceiverIdx = lastIndexOf(transceivers, transceiver =>
7038
- transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
7045
+ transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
7039
7046
 
7040
7047
  videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
7041
7048
  } else {
@@ -7281,10 +7288,13 @@ class WebRTCClient extends Emitter {
7281
7288
  return null;
7282
7289
  }
7283
7290
 
7284
- // let's update the local value
7285
- if (this.audio && this.audio.deviceId) {
7286
- // $FlowFixMe
7287
- this.audio.deviceId.exact = id;
7291
+ // let's update the local audio value
7292
+ if (this.audio) {
7293
+ this.audio = {
7294
+ deviceId: {
7295
+ exact: id,
7296
+ },
7297
+ };
7288
7298
  }
7289
7299
 
7290
7300
  if (session) {
@@ -7297,6 +7307,9 @@ class WebRTCClient extends Emitter {
7297
7307
  const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
7298
7308
 
7299
7309
  if (sender) {
7310
+ if (sender.track) {
7311
+ audioTrack.enabled = sender.track.enabled;
7312
+ }
7300
7313
  sender.replaceTrack(audioTrack);
7301
7314
  }
7302
7315
 
@@ -7321,7 +7334,7 @@ class WebRTCClient extends Emitter {
7321
7334
  return null;
7322
7335
  }
7323
7336
 
7324
- // let's update the local value
7337
+ // let's update the local video value
7325
7338
  if (this.video) {
7326
7339
  this.video = {
7327
7340
  deviceId: {
@@ -7356,12 +7369,21 @@ class WebRTCClient extends Emitter {
7356
7369
  return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
7357
7370
  const videoTrack = stream.getVideoTracks()[0];
7358
7371
  let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
7372
+ let wasTrackEnabled = false;
7359
7373
  if (!sender) {
7360
7374
  sender = pc && pc.getSenders().find(s => !s.track);
7361
7375
  }
7362
7376
 
7363
7377
  if (sender) {
7364
- sender.replaceTrack(videoTrack);
7378
+ // No video track means video not enabled
7379
+ wasTrackEnabled = sender.track ? sender.track.enabled : false;
7380
+ videoTrack.enabled = wasTrackEnabled;
7381
+
7382
+ if (!wasTrackEnabled) {
7383
+ videoTrack.stop();
7384
+ }
7385
+
7386
+ sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
7365
7387
  }
7366
7388
 
7367
7389
  // let's update the local stream
@@ -8045,6 +8067,7 @@ class WebRTCClient extends Emitter {
8045
8067
 
8046
8068
  this.updateRemoteStream(this.getSipSessionId(session));
8047
8069
 
8070
+ const pc = session.sessionDescriptionHandler.peerConnection;
8048
8071
  const onTrack = (event ) => {
8049
8072
  const isAudioOnly = this._isAudioOnly(session);
8050
8073
  const { kind, label, readyState, id, muted } = event.track;
@@ -8064,6 +8087,12 @@ class WebRTCClient extends Emitter {
8064
8087
 
8065
8088
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
8066
8089
 
8090
+ pc.oniceconnectionstatechange = () => {
8091
+ if (pc.iceConnectionState === 'disconnected') {
8092
+ this.eventEmitter.emit(ON_DISCONNECTED$1);
8093
+ }
8094
+ };
8095
+
8067
8096
  if (withEvent) {
8068
8097
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
8069
8098
  }
@@ -8275,25 +8304,33 @@ class WebRTCClient extends Emitter {
8275
8304
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
8276
8305
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
8277
8306
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
8307
+ const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
8308
+ const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
8278
8309
  let audioBytesSent = 0;
8279
8310
  let audioBytesReceived = 0;
8280
8311
  let videoBytesSent = 0;
8281
8312
  let videoBytesReceived = 0;
8313
+ let transportSent = 0;
8314
+ let transportReceived = 0;
8315
+ let packetsLost = 0;
8282
8316
 
8283
8317
  stats.forEach(report => {
8284
8318
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
8319
+ audioBytesSent += report.bytesSent + report.headerBytesSent;
8320
+ }
8321
+ if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
8285
8322
  audioBytesSent += report.bytesSent;
8286
8323
  }
8287
8324
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
8288
- videoBytesSent += report.bytesSent;
8325
+ videoBytesSent += report.bytesSent + report.headerBytesSent;
8289
8326
  }
8290
8327
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
8291
- networkStats.packetsLost = report.packetsLost;
8328
+ packetsLost += report.packetsLost;
8292
8329
  networkStats.packetsReceived = report.packetsReceived;
8293
- audioBytesReceived += report.bytesReceived;
8330
+ audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
8294
8331
  }
8295
8332
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
8296
- videoBytesReceived += report.bytesReceived;
8333
+ videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
8297
8334
  }
8298
8335
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
8299
8336
  if ('framesPerSecond' in report) {
@@ -8305,19 +8342,32 @@ class WebRTCClient extends Emitter {
8305
8342
  }
8306
8343
  }
8307
8344
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
8345
+ packetsLost += report.packetsLost;
8308
8346
  networkStats.roundTripTime = report.roundTripTime;
8309
8347
  networkStats.jitter = report.jitter;
8310
8348
  }
8349
+ if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
8350
+ packetsLost += report.packetsLost;
8351
+ }
8352
+ if (report.type === 'transport') {
8353
+ transportSent += report.bytesSent;
8354
+ transportReceived += report.bytesReceived;
8355
+ }
8311
8356
  });
8312
8357
 
8358
+ networkStats.packetsLost = packetsLost;
8313
8359
  networkStats.audioBytesSent = audioBytesSent;
8314
8360
  networkStats.audioBytesReceived = audioBytesReceived;
8315
8361
  networkStats.videoBytesSent = videoBytesSent;
8316
8362
  networkStats.videoBytesReceived = videoBytesReceived;
8363
+ networkStats.transportSent = transportSent;
8364
+ networkStats.transportReceived = transportReceived;
8317
8365
 
8318
- networkStats.bandwidth = (networkStats.audioBytesSent - lastAudioSent)
8319
- + (networkStats.videoBytesSent - lastVideoSent) + (networkStats.audioBytesReceived - lastAudioReceived)
8320
- + (networkStats.videoBytesReceived - lastVideoReceived);
8366
+ const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
8367
+ + (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
8368
+ + (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
8369
+
8370
+ networkStats.bandwidth = bandwidth;
8321
8371
 
8322
8372
  this.eventEmitter.emit(ON_NETWORK_STATS$1, session, networkStats, this.sessionNetworkStats[sessionId]);
8323
8373
  this.sessionNetworkStats[sessionId].push(networkStats);
@@ -8366,6 +8416,7 @@ const ON_MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
8366
8416
  const ON_NETWORK_STATS = 'onNetworkStats';
8367
8417
  const ON_CHAT = 'phone/ON_CHAT';
8368
8418
  const ON_SIGNAL = 'phone/ON_SIGNAL';
8419
+ const ON_DISCONNECTED = 'onDisconnected';
8369
8420
 
8370
8421
  const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
8371
8422
  const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
@@ -8405,6 +8456,7 @@ const events = [
8405
8456
  ON_CHAT,
8406
8457
  ON_SIGNAL,
8407
8458
  ON_NETWORK_STATS,
8459
+ ON_DISCONNECTED,
8408
8460
  ];
8409
8461
 
8410
8462
  const logger$8 = IssueReporter$1.loggerFor('webrtc-phone');
@@ -9757,6 +9809,11 @@ class WebRTCPhone extends Emitter {
9757
9809
  this.eventEmitter.emit(ON_UNREGISTERED);
9758
9810
  });
9759
9811
 
9812
+ this.client.on(this.client.ON_DISCONNECTED, () => {
9813
+ logger$8.info('WebRTC disconnected');
9814
+ this.eventEmitter.emit(ON_DISCONNECTED);
9815
+ });
9816
+
9760
9817
  this.client.on(this.client.REGISTERED, () => {
9761
9818
  logger$8.info('WebRTC registered', {
9762
9819
  shouldSendReinvite: this.shouldSendReinvite,
@@ -10013,6 +10070,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10013
10070
  ON_NETWORK_STATS: ON_NETWORK_STATS,
10014
10071
  ON_CHAT: ON_CHAT,
10015
10072
  ON_SIGNAL: ON_SIGNAL,
10073
+ ON_DISCONNECTED: ON_DISCONNECTED,
10016
10074
  MESSAGE_TYPE_CHAT: MESSAGE_TYPE_CHAT,
10017
10075
  MESSAGE_TYPE_SIGNAL: MESSAGE_TYPE_SIGNAL,
10018
10076
  events: events,
@@ -381,7 +381,7 @@ class IssueReporter {
381
381
  payload._retry = retry + 1;
382
382
  }
383
383
 
384
- this._sendDebugToGrafana(body, retry + 1);
384
+ this._sendDebugToGrafana(payload, retry + 1);
385
385
  }, 5000 + retry * 1000);
386
386
  });
387
387
  }
@@ -1896,7 +1896,7 @@ class IssueReporter {
1896
1896
  payload._retry = retry + 1;
1897
1897
  }
1898
1898
 
1899
- this._sendDebugToGrafana(body, retry + 1);
1899
+ this._sendDebugToGrafana(payload, retry + 1);
1900
1900
  }, 5000 + retry * 1000);
1901
1901
  });
1902
1902
  }
@@ -2614,7 +2614,8 @@ class ExternalApp {
2614
2614
 
2615
2615
 
2616
2616
 
2617
-
2617
+
2618
+
2618
2619
 
2619
2620
 
2620
2621
  class Meeting {
@@ -2626,6 +2627,7 @@ class Meeting {
2626
2627
 
2627
2628
 
2628
2629
 
2630
+
2629
2631
 
2630
2632
 
2631
2633
  static parse(plain ) {
@@ -2637,6 +2639,7 @@ class Meeting {
2637
2639
  port: plain.port,
2638
2640
  uuid: plain.uuid,
2639
2641
  number: plain.number,
2642
+ persistent: plain.persistent,
2640
2643
  });
2641
2644
  }
2642
2645
 
@@ -2644,7 +2647,7 @@ class Meeting {
2644
2647
  return newFrom(meeting, Meeting);
2645
2648
  }
2646
2649
 
2647
- constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
2650
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
2648
2651
  this.guestSipAuthorization = guestSipAuthorization;
2649
2652
  this.uri = uri;
2650
2653
  this.name = name;
@@ -2652,6 +2655,7 @@ class Meeting {
2652
2655
  this.port = port;
2653
2656
  this.uuid = uuid;
2654
2657
  this.number = number;
2658
+ this.persistent = persistent;
2655
2659
 
2656
2660
  // Useful to compare instead of instanceof with minified code
2657
2661
  this.type = 'Meeting';
@@ -3586,7 +3590,7 @@ class Recording {
3586
3590
 
3587
3591
 
3588
3592
 
3589
- static parseMany(recordings ) {
3593
+ static parseMany(recordings = []) {
3590
3594
  return recordings.map(item => Recording.parse(item));
3591
3595
  }
3592
3596
 
@@ -3712,7 +3716,7 @@ class CallLog {
3712
3716
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3713
3717
  start: moment__default['default'](plain.start).toDate(),
3714
3718
  end: plain.end ? moment__default['default'](plain.end).toDate() : null,
3715
- recordings: Recording.parseMany(plain.recordings),
3719
+ recordings: Recording.parseMany(plain.recordings || []),
3716
3720
  });
3717
3721
  }
3718
3722
 
@@ -6557,6 +6561,7 @@ const ON_REINVITE$1 = 'reinvite';
6557
6561
  const ON_ERROR = 'onError';
6558
6562
  const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
6559
6563
  const ON_NETWORK_STATS$1 = 'onNetworkStats';
6564
+ const ON_DISCONNECTED$1 = 'onDisconnected';
6560
6565
 
6561
6566
  const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
6562
6567
  const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
@@ -6633,6 +6638,7 @@ class WebRTCClient extends Emitter {
6633
6638
 
6634
6639
 
6635
6640
 
6641
+
6636
6642
 
6637
6643
  static isAPrivateIp(ip ) {
6638
6644
  const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
@@ -6698,6 +6704,7 @@ class WebRTCClient extends Emitter {
6698
6704
  this.ON_ERROR = ON_ERROR;
6699
6705
  this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
6700
6706
  this.ON_NETWORK_STATS = ON_NETWORK_STATS$1;
6707
+ this.ON_DISCONNECTED = ON_DISCONNECTED$1;
6701
6708
  }
6702
6709
 
6703
6710
  configureMedia(media ) {
@@ -7299,7 +7306,7 @@ class WebRTCClient extends Emitter {
7299
7306
  // We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
7300
7307
  const transceivers = pc.getTransceivers();
7301
7308
  const transceiverIdx = lastIndexOf(transceivers, transceiver =>
7302
- transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
7309
+ transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
7303
7310
 
7304
7311
  videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
7305
7312
  } else {
@@ -7545,10 +7552,13 @@ class WebRTCClient extends Emitter {
7545
7552
  return null;
7546
7553
  }
7547
7554
 
7548
- // let's update the local value
7549
- if (this.audio && this.audio.deviceId) {
7550
- // $FlowFixMe
7551
- this.audio.deviceId.exact = id;
7555
+ // let's update the local audio value
7556
+ if (this.audio) {
7557
+ this.audio = {
7558
+ deviceId: {
7559
+ exact: id,
7560
+ },
7561
+ };
7552
7562
  }
7553
7563
 
7554
7564
  if (session) {
@@ -7561,6 +7571,9 @@ class WebRTCClient extends Emitter {
7561
7571
  const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
7562
7572
 
7563
7573
  if (sender) {
7574
+ if (sender.track) {
7575
+ audioTrack.enabled = sender.track.enabled;
7576
+ }
7564
7577
  sender.replaceTrack(audioTrack);
7565
7578
  }
7566
7579
 
@@ -7585,7 +7598,7 @@ class WebRTCClient extends Emitter {
7585
7598
  return null;
7586
7599
  }
7587
7600
 
7588
- // let's update the local value
7601
+ // let's update the local video value
7589
7602
  if (this.video) {
7590
7603
  this.video = {
7591
7604
  deviceId: {
@@ -7620,12 +7633,21 @@ class WebRTCClient extends Emitter {
7620
7633
  return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
7621
7634
  const videoTrack = stream.getVideoTracks()[0];
7622
7635
  let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
7636
+ let wasTrackEnabled = false;
7623
7637
  if (!sender) {
7624
7638
  sender = pc && pc.getSenders().find(s => !s.track);
7625
7639
  }
7626
7640
 
7627
7641
  if (sender) {
7628
- sender.replaceTrack(videoTrack);
7642
+ // No video track means video not enabled
7643
+ wasTrackEnabled = sender.track ? sender.track.enabled : false;
7644
+ videoTrack.enabled = wasTrackEnabled;
7645
+
7646
+ if (!wasTrackEnabled) {
7647
+ videoTrack.stop();
7648
+ }
7649
+
7650
+ sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
7629
7651
  }
7630
7652
 
7631
7653
  // let's update the local stream
@@ -8309,6 +8331,7 @@ class WebRTCClient extends Emitter {
8309
8331
 
8310
8332
  this.updateRemoteStream(this.getSipSessionId(session));
8311
8333
 
8334
+ const pc = session.sessionDescriptionHandler.peerConnection;
8312
8335
  const onTrack = (event ) => {
8313
8336
  const isAudioOnly = this._isAudioOnly(session);
8314
8337
  const { kind, label, readyState, id, muted } = event.track;
@@ -8328,6 +8351,12 @@ class WebRTCClient extends Emitter {
8328
8351
 
8329
8352
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
8330
8353
 
8354
+ pc.oniceconnectionstatechange = () => {
8355
+ if (pc.iceConnectionState === 'disconnected') {
8356
+ this.eventEmitter.emit(ON_DISCONNECTED$1);
8357
+ }
8358
+ };
8359
+
8331
8360
  if (withEvent) {
8332
8361
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
8333
8362
  }
@@ -8539,25 +8568,33 @@ class WebRTCClient extends Emitter {
8539
8568
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
8540
8569
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
8541
8570
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
8571
+ const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
8572
+ const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
8542
8573
  let audioBytesSent = 0;
8543
8574
  let audioBytesReceived = 0;
8544
8575
  let videoBytesSent = 0;
8545
8576
  let videoBytesReceived = 0;
8577
+ let transportSent = 0;
8578
+ let transportReceived = 0;
8579
+ let packetsLost = 0;
8546
8580
 
8547
8581
  stats.forEach(report => {
8548
8582
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
8583
+ audioBytesSent += report.bytesSent + report.headerBytesSent;
8584
+ }
8585
+ if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
8549
8586
  audioBytesSent += report.bytesSent;
8550
8587
  }
8551
8588
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
8552
- videoBytesSent += report.bytesSent;
8589
+ videoBytesSent += report.bytesSent + report.headerBytesSent;
8553
8590
  }
8554
8591
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
8555
- networkStats.packetsLost = report.packetsLost;
8592
+ packetsLost += report.packetsLost;
8556
8593
  networkStats.packetsReceived = report.packetsReceived;
8557
- audioBytesReceived += report.bytesReceived;
8594
+ audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
8558
8595
  }
8559
8596
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
8560
- videoBytesReceived += report.bytesReceived;
8597
+ videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
8561
8598
  }
8562
8599
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
8563
8600
  if ('framesPerSecond' in report) {
@@ -8569,19 +8606,32 @@ class WebRTCClient extends Emitter {
8569
8606
  }
8570
8607
  }
8571
8608
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
8609
+ packetsLost += report.packetsLost;
8572
8610
  networkStats.roundTripTime = report.roundTripTime;
8573
8611
  networkStats.jitter = report.jitter;
8574
8612
  }
8613
+ if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
8614
+ packetsLost += report.packetsLost;
8615
+ }
8616
+ if (report.type === 'transport') {
8617
+ transportSent += report.bytesSent;
8618
+ transportReceived += report.bytesReceived;
8619
+ }
8575
8620
  });
8576
8621
 
8622
+ networkStats.packetsLost = packetsLost;
8577
8623
  networkStats.audioBytesSent = audioBytesSent;
8578
8624
  networkStats.audioBytesReceived = audioBytesReceived;
8579
8625
  networkStats.videoBytesSent = videoBytesSent;
8580
8626
  networkStats.videoBytesReceived = videoBytesReceived;
8627
+ networkStats.transportSent = transportSent;
8628
+ networkStats.transportReceived = transportReceived;
8581
8629
 
8582
- networkStats.bandwidth = (networkStats.audioBytesSent - lastAudioSent)
8583
- + (networkStats.videoBytesSent - lastVideoSent) + (networkStats.audioBytesReceived - lastAudioReceived)
8584
- + (networkStats.videoBytesReceived - lastVideoReceived);
8630
+ const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
8631
+ + (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
8632
+ + (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
8633
+
8634
+ networkStats.bandwidth = bandwidth;
8585
8635
 
8586
8636
  this.eventEmitter.emit(ON_NETWORK_STATS$1, session, networkStats, this.sessionNetworkStats[sessionId]);
8587
8637
  this.sessionNetworkStats[sessionId].push(networkStats);
@@ -8630,6 +8680,7 @@ const ON_MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
8630
8680
  const ON_NETWORK_STATS = 'onNetworkStats';
8631
8681
  const ON_CHAT = 'phone/ON_CHAT';
8632
8682
  const ON_SIGNAL = 'phone/ON_SIGNAL';
8683
+ const ON_DISCONNECTED = 'onDisconnected';
8633
8684
 
8634
8685
  const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
8635
8686
  const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
@@ -8669,6 +8720,7 @@ const events = [
8669
8720
  ON_CHAT,
8670
8721
  ON_SIGNAL,
8671
8722
  ON_NETWORK_STATS,
8723
+ ON_DISCONNECTED,
8672
8724
  ];
8673
8725
 
8674
8726
  const logger$7 = IssueReporter$1.loggerFor('webrtc-phone');
@@ -10021,6 +10073,11 @@ class WebRTCPhone extends Emitter {
10021
10073
  this.eventEmitter.emit(ON_UNREGISTERED);
10022
10074
  });
10023
10075
 
10076
+ this.client.on(this.client.ON_DISCONNECTED, () => {
10077
+ logger$7.info('WebRTC disconnected');
10078
+ this.eventEmitter.emit(ON_DISCONNECTED);
10079
+ });
10080
+
10024
10081
  this.client.on(this.client.REGISTERED, () => {
10025
10082
  logger$7.info('WebRTC registered', {
10026
10083
  shouldSendReinvite: this.shouldSendReinvite,
@@ -10277,6 +10334,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10277
10334
  ON_NETWORK_STATS: ON_NETWORK_STATS,
10278
10335
  ON_CHAT: ON_CHAT,
10279
10336
  ON_SIGNAL: ON_SIGNAL,
10337
+ ON_DISCONNECTED: ON_DISCONNECTED,
10280
10338
  MESSAGE_TYPE_CHAT: MESSAGE_TYPE_CHAT,
10281
10339
  MESSAGE_TYPE_SIGNAL: MESSAGE_TYPE_SIGNAL,
10282
10340
  events: events,