@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.
Files changed (114) hide show
  1. package/dist/wazo-sdk.js +3 -3
  2. package/esm/__tests__/api-client.test.js +9 -5
  3. package/esm/__tests__/web-rtc-client.test.js +117 -23
  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 +117 -23
  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 +117 -23
  20. package/esm/checker/checks/wazo-websocket.js +1 -1
  21. package/esm/checker/checks/webrtc-transport.js +117 -23
  22. package/esm/checker/checks/webrtc.js +117 -23
  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 +125 -23
  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 +125 -23
  38. package/esm/simple/Configuration.js +125 -23
  39. package/esm/simple/Directory.js +9 -5
  40. package/esm/simple/Phone.js +125 -23
  41. package/esm/simple/Websocket.js +1 -1
  42. package/esm/simple/index.js +125 -23
  43. package/esm/simple/room/LocalParticipant.js +125 -23
  44. package/esm/simple/room/Participant.js +125 -23
  45. package/esm/simple/room/RemoteParticipant.js +125 -23
  46. package/esm/simple/room/Room.js +125 -23
  47. package/esm/simple/room/SipRoom.js +125 -23
  48. package/esm/simple/room/Stream.js +125 -23
  49. package/esm/simple/room/__tests__/RemoteParticipant.test.js +125 -23
  50. package/esm/simple/utils.js +125 -23
  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 +117 -23
  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 +117 -23
  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 +117 -23
  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 +117 -23
  73. package/lib/checker/checks/wazo-websocket.js +1 -1
  74. package/lib/checker/checks/webrtc-transport.js +117 -23
  75. package/lib/checker/checks/webrtc.js +117 -23
  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 +125 -23
  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 +125 -23
  91. package/lib/simple/Configuration.js +125 -23
  92. package/lib/simple/Directory.js +9 -5
  93. package/lib/simple/Phone.js +125 -23
  94. package/lib/simple/Websocket.js +1 -1
  95. package/lib/simple/index.js +125 -23
  96. package/lib/simple/room/LocalParticipant.js +125 -23
  97. package/lib/simple/room/Participant.js +125 -23
  98. package/lib/simple/room/RemoteParticipant.js +125 -23
  99. package/lib/simple/room/Room.js +125 -23
  100. package/lib/simple/room/SipRoom.js +125 -23
  101. package/lib/simple/room/Stream.js +125 -23
  102. package/lib/simple/room/__tests__/RemoteParticipant.test.js +125 -23
  103. package/lib/simple/utils.js +125 -23
  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 +117 -23
  107. package/lib/websocket-client.js +1 -1
  108. package/package.json +1 -1
  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 +108 -18
@@ -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
  }
@@ -8523,24 +8552,89 @@ class WebRTCClient extends Emitter {
8523
8552
  const session = this.getSipSession(sessionId);
8524
8553
 
8525
8554
  const stats = session ? await this.getStats(session) : null;
8526
- if (!stats) {
8555
+ if (!stats || !(sessionId in this.sessionNetworkStats)) {
8527
8556
  return;
8528
8557
  }
8529
8558
 
8530
- stats.forEach(report => {
8531
- if (report.type === 'inbound-rtp') {
8532
- if (report.kind === 'audio') {
8533
- const networkStats = {
8534
- packetsLost: report.packetsLost,
8535
- packetsReceived: report.packetsReceived,
8536
- jitter: report.jitter,
8537
- };
8559
+ const networkStats = {
8560
+ audioBytesSent: 0,
8561
+ videoBytesSent: 0,
8562
+ videoBytesReceived: 0,
8563
+ audioBytesReceived: 0,
8564
+ };
8565
+ const nbStats = this.sessionNetworkStats[sessionId].length;
8566
+ const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
8567
+ const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
8568
+ const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
8569
+ const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
8570
+ const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
8571
+ const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
8572
+ const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
8573
+ let audioBytesSent = 0;
8574
+ let audioBytesReceived = 0;
8575
+ let videoBytesSent = 0;
8576
+ let videoBytesReceived = 0;
8577
+ let transportSent = 0;
8578
+ let transportReceived = 0;
8579
+ let packetsLost = 0;
8538
8580
 
8539
- this.eventEmitter.emit(ON_NETWORK_STATS$1, session, networkStats, this.sessionNetworkStats[sessionId]);
8540
- this.sessionNetworkStats[sessionId].push(networkStats);
8581
+ stats.forEach(report => {
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') {
8586
+ audioBytesSent += report.bytesSent;
8587
+ }
8588
+ if (report.type === 'outbound-rtp' && report.kind === 'video') {
8589
+ videoBytesSent += report.bytesSent + report.headerBytesSent;
8590
+ }
8591
+ if (report.type === 'inbound-rtp' && report.kind === 'audio') {
8592
+ packetsLost += report.packetsLost;
8593
+ networkStats.packetsReceived = report.packetsReceived;
8594
+ audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
8595
+ }
8596
+ if (report.type === 'inbound-rtp' && report.kind === 'video') {
8597
+ videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
8598
+ }
8599
+ if (report.type === 'outbound-rtp' && report.kind === 'video') {
8600
+ if ('framesPerSecond' in report) {
8601
+ networkStats.framesPerSecond = report.framesPerSecond;
8602
+ }
8603
+ if ('framerateMean' in report) {
8604
+ // framerateMean is only available in FF
8605
+ networkStats.framesPerSecond = Math.round(report.framerateMean);
8541
8606
  }
8542
8607
  }
8608
+ if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
8609
+ packetsLost += report.packetsLost;
8610
+ networkStats.roundTripTime = report.roundTripTime;
8611
+ networkStats.jitter = report.jitter;
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
+ }
8543
8620
  });
8621
+
8622
+ networkStats.packetsLost = packetsLost;
8623
+ networkStats.audioBytesSent = audioBytesSent;
8624
+ networkStats.audioBytesReceived = audioBytesReceived;
8625
+ networkStats.videoBytesSent = videoBytesSent;
8626
+ networkStats.videoBytesReceived = videoBytesReceived;
8627
+ networkStats.transportSent = transportSent;
8628
+ networkStats.transportReceived = transportReceived;
8629
+
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;
8635
+
8636
+ this.eventEmitter.emit(ON_NETWORK_STATS$1, session, networkStats, this.sessionNetworkStats[sessionId]);
8637
+ this.sessionNetworkStats[sessionId].push(networkStats);
8544
8638
  }
8545
8639
 
8546
8640
  }
@@ -8586,6 +8680,7 @@ const ON_MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
8586
8680
  const ON_NETWORK_STATS = 'onNetworkStats';
8587
8681
  const ON_CHAT = 'phone/ON_CHAT';
8588
8682
  const ON_SIGNAL = 'phone/ON_SIGNAL';
8683
+ const ON_DISCONNECTED = 'onDisconnected';
8589
8684
 
8590
8685
  const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
8591
8686
  const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
@@ -8625,6 +8720,7 @@ const events = [
8625
8720
  ON_CHAT,
8626
8721
  ON_SIGNAL,
8627
8722
  ON_NETWORK_STATS,
8723
+ ON_DISCONNECTED,
8628
8724
  ];
8629
8725
 
8630
8726
  const logger$7 = IssueReporter$1.loggerFor('webrtc-phone');
@@ -9977,6 +10073,11 @@ class WebRTCPhone extends Emitter {
9977
10073
  this.eventEmitter.emit(ON_UNREGISTERED);
9978
10074
  });
9979
10075
 
10076
+ this.client.on(this.client.ON_DISCONNECTED, () => {
10077
+ logger$7.info('WebRTC disconnected');
10078
+ this.eventEmitter.emit(ON_DISCONNECTED);
10079
+ });
10080
+
9980
10081
  this.client.on(this.client.REGISTERED, () => {
9981
10082
  logger$7.info('WebRTC registered', {
9982
10083
  shouldSendReinvite: this.shouldSendReinvite,
@@ -10233,6 +10334,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10233
10334
  ON_NETWORK_STATS: ON_NETWORK_STATS,
10234
10335
  ON_CHAT: ON_CHAT,
10235
10336
  ON_SIGNAL: ON_SIGNAL,
10337
+ ON_DISCONNECTED: ON_DISCONNECTED,
10236
10338
  MESSAGE_TYPE_CHAT: MESSAGE_TYPE_CHAT,
10237
10339
  MESSAGE_TYPE_SIGNAL: MESSAGE_TYPE_SIGNAL,
10238
10340
  events: events,
@@ -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
  }
@@ -8523,24 +8552,89 @@ class WebRTCClient extends Emitter {
8523
8552
  const session = this.getSipSession(sessionId);
8524
8553
 
8525
8554
  const stats = session ? await this.getStats(session) : null;
8526
- if (!stats) {
8555
+ if (!stats || !(sessionId in this.sessionNetworkStats)) {
8527
8556
  return;
8528
8557
  }
8529
8558
 
8530
- stats.forEach(report => {
8531
- if (report.type === 'inbound-rtp') {
8532
- if (report.kind === 'audio') {
8533
- const networkStats = {
8534
- packetsLost: report.packetsLost,
8535
- packetsReceived: report.packetsReceived,
8536
- jitter: report.jitter,
8537
- };
8559
+ const networkStats = {
8560
+ audioBytesSent: 0,
8561
+ videoBytesSent: 0,
8562
+ videoBytesReceived: 0,
8563
+ audioBytesReceived: 0,
8564
+ };
8565
+ const nbStats = this.sessionNetworkStats[sessionId].length;
8566
+ const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
8567
+ const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
8568
+ const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
8569
+ const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
8570
+ const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
8571
+ const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
8572
+ const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
8573
+ let audioBytesSent = 0;
8574
+ let audioBytesReceived = 0;
8575
+ let videoBytesSent = 0;
8576
+ let videoBytesReceived = 0;
8577
+ let transportSent = 0;
8578
+ let transportReceived = 0;
8579
+ let packetsLost = 0;
8538
8580
 
8539
- this.eventEmitter.emit(ON_NETWORK_STATS$1, session, networkStats, this.sessionNetworkStats[sessionId]);
8540
- this.sessionNetworkStats[sessionId].push(networkStats);
8581
+ stats.forEach(report => {
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') {
8586
+ audioBytesSent += report.bytesSent;
8587
+ }
8588
+ if (report.type === 'outbound-rtp' && report.kind === 'video') {
8589
+ videoBytesSent += report.bytesSent + report.headerBytesSent;
8590
+ }
8591
+ if (report.type === 'inbound-rtp' && report.kind === 'audio') {
8592
+ packetsLost += report.packetsLost;
8593
+ networkStats.packetsReceived = report.packetsReceived;
8594
+ audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
8595
+ }
8596
+ if (report.type === 'inbound-rtp' && report.kind === 'video') {
8597
+ videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
8598
+ }
8599
+ if (report.type === 'outbound-rtp' && report.kind === 'video') {
8600
+ if ('framesPerSecond' in report) {
8601
+ networkStats.framesPerSecond = report.framesPerSecond;
8602
+ }
8603
+ if ('framerateMean' in report) {
8604
+ // framerateMean is only available in FF
8605
+ networkStats.framesPerSecond = Math.round(report.framerateMean);
8541
8606
  }
8542
8607
  }
8608
+ if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
8609
+ packetsLost += report.packetsLost;
8610
+ networkStats.roundTripTime = report.roundTripTime;
8611
+ networkStats.jitter = report.jitter;
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
+ }
8543
8620
  });
8621
+
8622
+ networkStats.packetsLost = packetsLost;
8623
+ networkStats.audioBytesSent = audioBytesSent;
8624
+ networkStats.audioBytesReceived = audioBytesReceived;
8625
+ networkStats.videoBytesSent = videoBytesSent;
8626
+ networkStats.videoBytesReceived = videoBytesReceived;
8627
+ networkStats.transportSent = transportSent;
8628
+ networkStats.transportReceived = transportReceived;
8629
+
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;
8635
+
8636
+ this.eventEmitter.emit(ON_NETWORK_STATS$1, session, networkStats, this.sessionNetworkStats[sessionId]);
8637
+ this.sessionNetworkStats[sessionId].push(networkStats);
8544
8638
  }
8545
8639
 
8546
8640
  }
@@ -8586,6 +8680,7 @@ const ON_MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
8586
8680
  const ON_NETWORK_STATS = 'onNetworkStats';
8587
8681
  const ON_CHAT = 'phone/ON_CHAT';
8588
8682
  const ON_SIGNAL = 'phone/ON_SIGNAL';
8683
+ const ON_DISCONNECTED = 'onDisconnected';
8589
8684
 
8590
8685
  const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
8591
8686
  const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
@@ -8625,6 +8720,7 @@ const events = [
8625
8720
  ON_CHAT,
8626
8721
  ON_SIGNAL,
8627
8722
  ON_NETWORK_STATS,
8723
+ ON_DISCONNECTED,
8628
8724
  ];
8629
8725
 
8630
8726
  const logger$7 = IssueReporter$1.loggerFor('webrtc-phone');
@@ -9977,6 +10073,11 @@ class WebRTCPhone extends Emitter {
9977
10073
  this.eventEmitter.emit(ON_UNREGISTERED);
9978
10074
  });
9979
10075
 
10076
+ this.client.on(this.client.ON_DISCONNECTED, () => {
10077
+ logger$7.info('WebRTC disconnected');
10078
+ this.eventEmitter.emit(ON_DISCONNECTED);
10079
+ });
10080
+
9980
10081
  this.client.on(this.client.REGISTERED, () => {
9981
10082
  logger$7.info('WebRTC registered', {
9982
10083
  shouldSendReinvite: this.shouldSendReinvite,
@@ -10233,6 +10334,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10233
10334
  ON_NETWORK_STATS: ON_NETWORK_STATS,
10234
10335
  ON_CHAT: ON_CHAT,
10235
10336
  ON_SIGNAL: ON_SIGNAL,
10337
+ ON_DISCONNECTED: ON_DISCONNECTED,
10236
10338
  MESSAGE_TYPE_CHAT: MESSAGE_TYPE_CHAT,
10237
10339
  MESSAGE_TYPE_SIGNAL: MESSAGE_TYPE_SIGNAL,
10238
10340
  events: events,