@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
@@ -401,7 +401,7 @@ class IssueReporter {
401
401
  payload._retry = retry + 1;
402
402
  }
403
403
 
404
- this._sendDebugToGrafana(body, retry + 1);
404
+ this._sendDebugToGrafana(payload, retry + 1);
405
405
  }, 5000 + retry * 1000);
406
406
  });
407
407
  }
@@ -2604,7 +2604,8 @@ class ExternalApp {
2604
2604
 
2605
2605
 
2606
2606
 
2607
-
2607
+
2608
+
2608
2609
 
2609
2610
 
2610
2611
  class Meeting {
@@ -2616,6 +2617,7 @@ class Meeting {
2616
2617
 
2617
2618
 
2618
2619
 
2620
+
2619
2621
 
2620
2622
 
2621
2623
  static parse(plain ) {
@@ -2627,6 +2629,7 @@ class Meeting {
2627
2629
  port: plain.port,
2628
2630
  uuid: plain.uuid,
2629
2631
  number: plain.number,
2632
+ persistent: plain.persistent,
2630
2633
  });
2631
2634
  }
2632
2635
 
@@ -2634,7 +2637,7 @@ class Meeting {
2634
2637
  return newFrom(meeting, Meeting);
2635
2638
  }
2636
2639
 
2637
- constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
2640
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
2638
2641
  this.guestSipAuthorization = guestSipAuthorization;
2639
2642
  this.uri = uri;
2640
2643
  this.name = name;
@@ -2642,6 +2645,7 @@ class Meeting {
2642
2645
  this.port = port;
2643
2646
  this.uuid = uuid;
2644
2647
  this.number = number;
2648
+ this.persistent = persistent;
2645
2649
 
2646
2650
  // Useful to compare instead of instanceof with minified code
2647
2651
  this.type = 'Meeting';
@@ -3576,7 +3580,7 @@ class Recording {
3576
3580
 
3577
3581
 
3578
3582
 
3579
- static parseMany(recordings ) {
3583
+ static parseMany(recordings = []) {
3580
3584
  return recordings.map(item => Recording.parse(item));
3581
3585
  }
3582
3586
 
@@ -3702,7 +3706,7 @@ class CallLog {
3702
3706
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3703
3707
  start: moment(plain.start).toDate(),
3704
3708
  end: plain.end ? moment(plain.end).toDate() : null,
3705
- recordings: Recording.parseMany(plain.recordings),
3709
+ recordings: Recording.parseMany(plain.recordings || []),
3706
3710
  });
3707
3711
  }
3708
3712
 
@@ -6547,6 +6551,7 @@ const ON_REINVITE$1 = 'reinvite';
6547
6551
  const ON_ERROR = 'onError';
6548
6552
  const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
6549
6553
  const ON_NETWORK_STATS$1 = 'onNetworkStats';
6554
+ const ON_DISCONNECTED$1 = 'onDisconnected';
6550
6555
 
6551
6556
  const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
6552
6557
  const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
@@ -6623,6 +6628,7 @@ class WebRTCClient extends Emitter {
6623
6628
 
6624
6629
 
6625
6630
 
6631
+
6626
6632
 
6627
6633
  static isAPrivateIp(ip ) {
6628
6634
  const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
@@ -6688,6 +6694,7 @@ class WebRTCClient extends Emitter {
6688
6694
  this.ON_ERROR = ON_ERROR;
6689
6695
  this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
6690
6696
  this.ON_NETWORK_STATS = ON_NETWORK_STATS$1;
6697
+ this.ON_DISCONNECTED = ON_DISCONNECTED$1;
6691
6698
  }
6692
6699
 
6693
6700
  configureMedia(media ) {
@@ -7289,7 +7296,7 @@ class WebRTCClient extends Emitter {
7289
7296
  // We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
7290
7297
  const transceivers = pc.getTransceivers();
7291
7298
  const transceiverIdx = lastIndexOf(transceivers, transceiver =>
7292
- transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
7299
+ transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
7293
7300
 
7294
7301
  videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
7295
7302
  } else {
@@ -7535,10 +7542,13 @@ class WebRTCClient extends Emitter {
7535
7542
  return null;
7536
7543
  }
7537
7544
 
7538
- // let's update the local value
7539
- if (this.audio && this.audio.deviceId) {
7540
- // $FlowFixMe
7541
- this.audio.deviceId.exact = id;
7545
+ // let's update the local audio value
7546
+ if (this.audio) {
7547
+ this.audio = {
7548
+ deviceId: {
7549
+ exact: id,
7550
+ },
7551
+ };
7542
7552
  }
7543
7553
 
7544
7554
  if (session) {
@@ -7551,6 +7561,9 @@ class WebRTCClient extends Emitter {
7551
7561
  const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
7552
7562
 
7553
7563
  if (sender) {
7564
+ if (sender.track) {
7565
+ audioTrack.enabled = sender.track.enabled;
7566
+ }
7554
7567
  sender.replaceTrack(audioTrack);
7555
7568
  }
7556
7569
 
@@ -7575,7 +7588,7 @@ class WebRTCClient extends Emitter {
7575
7588
  return null;
7576
7589
  }
7577
7590
 
7578
- // let's update the local value
7591
+ // let's update the local video value
7579
7592
  if (this.video) {
7580
7593
  this.video = {
7581
7594
  deviceId: {
@@ -7610,12 +7623,21 @@ class WebRTCClient extends Emitter {
7610
7623
  return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
7611
7624
  const videoTrack = stream.getVideoTracks()[0];
7612
7625
  let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
7626
+ let wasTrackEnabled = false;
7613
7627
  if (!sender) {
7614
7628
  sender = pc && pc.getSenders().find(s => !s.track);
7615
7629
  }
7616
7630
 
7617
7631
  if (sender) {
7618
- sender.replaceTrack(videoTrack);
7632
+ // No video track means video not enabled
7633
+ wasTrackEnabled = sender.track ? sender.track.enabled : false;
7634
+ videoTrack.enabled = wasTrackEnabled;
7635
+
7636
+ if (!wasTrackEnabled) {
7637
+ videoTrack.stop();
7638
+ }
7639
+
7640
+ sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
7619
7641
  }
7620
7642
 
7621
7643
  // let's update the local stream
@@ -8299,6 +8321,7 @@ class WebRTCClient extends Emitter {
8299
8321
 
8300
8322
  this.updateRemoteStream(this.getSipSessionId(session));
8301
8323
 
8324
+ const pc = session.sessionDescriptionHandler.peerConnection;
8302
8325
  const onTrack = (event ) => {
8303
8326
  const isAudioOnly = this._isAudioOnly(session);
8304
8327
  const { kind, label, readyState, id, muted } = event.track;
@@ -8318,6 +8341,12 @@ class WebRTCClient extends Emitter {
8318
8341
 
8319
8342
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
8320
8343
 
8344
+ pc.oniceconnectionstatechange = () => {
8345
+ if (pc.iceConnectionState === 'disconnected') {
8346
+ this.eventEmitter.emit(ON_DISCONNECTED$1);
8347
+ }
8348
+ };
8349
+
8321
8350
  if (withEvent) {
8322
8351
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
8323
8352
  }
@@ -8529,25 +8558,33 @@ class WebRTCClient extends Emitter {
8529
8558
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
8530
8559
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
8531
8560
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
8561
+ const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
8562
+ const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
8532
8563
  let audioBytesSent = 0;
8533
8564
  let audioBytesReceived = 0;
8534
8565
  let videoBytesSent = 0;
8535
8566
  let videoBytesReceived = 0;
8567
+ let transportSent = 0;
8568
+ let transportReceived = 0;
8569
+ let packetsLost = 0;
8536
8570
 
8537
8571
  stats.forEach(report => {
8538
8572
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
8573
+ audioBytesSent += report.bytesSent + report.headerBytesSent;
8574
+ }
8575
+ if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
8539
8576
  audioBytesSent += report.bytesSent;
8540
8577
  }
8541
8578
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
8542
- videoBytesSent += report.bytesSent;
8579
+ videoBytesSent += report.bytesSent + report.headerBytesSent;
8543
8580
  }
8544
8581
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
8545
- networkStats.packetsLost = report.packetsLost;
8582
+ packetsLost += report.packetsLost;
8546
8583
  networkStats.packetsReceived = report.packetsReceived;
8547
- audioBytesReceived += report.bytesReceived;
8584
+ audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
8548
8585
  }
8549
8586
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
8550
- videoBytesReceived += report.bytesReceived;
8587
+ videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
8551
8588
  }
8552
8589
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
8553
8590
  if ('framesPerSecond' in report) {
@@ -8559,19 +8596,32 @@ class WebRTCClient extends Emitter {
8559
8596
  }
8560
8597
  }
8561
8598
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
8599
+ packetsLost += report.packetsLost;
8562
8600
  networkStats.roundTripTime = report.roundTripTime;
8563
8601
  networkStats.jitter = report.jitter;
8564
8602
  }
8603
+ if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
8604
+ packetsLost += report.packetsLost;
8605
+ }
8606
+ if (report.type === 'transport') {
8607
+ transportSent += report.bytesSent;
8608
+ transportReceived += report.bytesReceived;
8609
+ }
8565
8610
  });
8566
8611
 
8612
+ networkStats.packetsLost = packetsLost;
8567
8613
  networkStats.audioBytesSent = audioBytesSent;
8568
8614
  networkStats.audioBytesReceived = audioBytesReceived;
8569
8615
  networkStats.videoBytesSent = videoBytesSent;
8570
8616
  networkStats.videoBytesReceived = videoBytesReceived;
8617
+ networkStats.transportSent = transportSent;
8618
+ networkStats.transportReceived = transportReceived;
8571
8619
 
8572
- networkStats.bandwidth = (networkStats.audioBytesSent - lastAudioSent)
8573
- + (networkStats.videoBytesSent - lastVideoSent) + (networkStats.audioBytesReceived - lastAudioReceived)
8574
- + (networkStats.videoBytesReceived - lastVideoReceived);
8620
+ const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
8621
+ + (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
8622
+ + (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
8623
+
8624
+ networkStats.bandwidth = bandwidth;
8575
8625
 
8576
8626
  this.eventEmitter.emit(ON_NETWORK_STATS$1, session, networkStats, this.sessionNetworkStats[sessionId]);
8577
8627
  this.sessionNetworkStats[sessionId].push(networkStats);
@@ -8620,6 +8670,7 @@ const ON_MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
8620
8670
  const ON_NETWORK_STATS = 'onNetworkStats';
8621
8671
  const ON_CHAT = 'phone/ON_CHAT';
8622
8672
  const ON_SIGNAL = 'phone/ON_SIGNAL';
8673
+ const ON_DISCONNECTED = 'onDisconnected';
8623
8674
 
8624
8675
  const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
8625
8676
  const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
@@ -8659,6 +8710,7 @@ const events = [
8659
8710
  ON_CHAT,
8660
8711
  ON_SIGNAL,
8661
8712
  ON_NETWORK_STATS,
8713
+ ON_DISCONNECTED,
8662
8714
  ];
8663
8715
 
8664
8716
  const logger$7 = IssueReporter$1.loggerFor('webrtc-phone');
@@ -10011,6 +10063,11 @@ class WebRTCPhone extends Emitter {
10011
10063
  this.eventEmitter.emit(ON_UNREGISTERED);
10012
10064
  });
10013
10065
 
10066
+ this.client.on(this.client.ON_DISCONNECTED, () => {
10067
+ logger$7.info('WebRTC disconnected');
10068
+ this.eventEmitter.emit(ON_DISCONNECTED);
10069
+ });
10070
+
10014
10071
  this.client.on(this.client.REGISTERED, () => {
10015
10072
  logger$7.info('WebRTC registered', {
10016
10073
  shouldSendReinvite: this.shouldSendReinvite,
@@ -10267,6 +10324,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10267
10324
  ON_NETWORK_STATS: ON_NETWORK_STATS,
10268
10325
  ON_CHAT: ON_CHAT,
10269
10326
  ON_SIGNAL: ON_SIGNAL,
10327
+ ON_DISCONNECTED: ON_DISCONNECTED,
10270
10328
  MESSAGE_TYPE_CHAT: MESSAGE_TYPE_CHAT,
10271
10329
  MESSAGE_TYPE_SIGNAL: MESSAGE_TYPE_SIGNAL,
10272
10330
  events: events,
@@ -401,7 +401,7 @@ class IssueReporter {
401
401
  payload._retry = retry + 1;
402
402
  }
403
403
 
404
- this._sendDebugToGrafana(body, retry + 1);
404
+ this._sendDebugToGrafana(payload, retry + 1);
405
405
  }, 5000 + retry * 1000);
406
406
  });
407
407
  }
@@ -2604,7 +2604,8 @@ class ExternalApp {
2604
2604
 
2605
2605
 
2606
2606
 
2607
-
2607
+
2608
+
2608
2609
 
2609
2610
 
2610
2611
  class Meeting {
@@ -2616,6 +2617,7 @@ class Meeting {
2616
2617
 
2617
2618
 
2618
2619
 
2620
+
2619
2621
 
2620
2622
 
2621
2623
  static parse(plain ) {
@@ -2627,6 +2629,7 @@ class Meeting {
2627
2629
  port: plain.port,
2628
2630
  uuid: plain.uuid,
2629
2631
  number: plain.number,
2632
+ persistent: plain.persistent,
2630
2633
  });
2631
2634
  }
2632
2635
 
@@ -2634,7 +2637,7 @@ class Meeting {
2634
2637
  return newFrom(meeting, Meeting);
2635
2638
  }
2636
2639
 
2637
- constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
2640
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
2638
2641
  this.guestSipAuthorization = guestSipAuthorization;
2639
2642
  this.uri = uri;
2640
2643
  this.name = name;
@@ -2642,6 +2645,7 @@ class Meeting {
2642
2645
  this.port = port;
2643
2646
  this.uuid = uuid;
2644
2647
  this.number = number;
2648
+ this.persistent = persistent;
2645
2649
 
2646
2650
  // Useful to compare instead of instanceof with minified code
2647
2651
  this.type = 'Meeting';
@@ -3576,7 +3580,7 @@ class Recording {
3576
3580
 
3577
3581
 
3578
3582
 
3579
- static parseMany(recordings ) {
3583
+ static parseMany(recordings = []) {
3580
3584
  return recordings.map(item => Recording.parse(item));
3581
3585
  }
3582
3586
 
@@ -3702,7 +3706,7 @@ class CallLog {
3702
3706
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3703
3707
  start: moment(plain.start).toDate(),
3704
3708
  end: plain.end ? moment(plain.end).toDate() : null,
3705
- recordings: Recording.parseMany(plain.recordings),
3709
+ recordings: Recording.parseMany(plain.recordings || []),
3706
3710
  });
3707
3711
  }
3708
3712
 
@@ -6547,6 +6551,7 @@ const ON_REINVITE$1 = 'reinvite';
6547
6551
  const ON_ERROR = 'onError';
6548
6552
  const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
6549
6553
  const ON_NETWORK_STATS$1 = 'onNetworkStats';
6554
+ const ON_DISCONNECTED$1 = 'onDisconnected';
6550
6555
 
6551
6556
  const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
6552
6557
  const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
@@ -6623,6 +6628,7 @@ class WebRTCClient extends Emitter {
6623
6628
 
6624
6629
 
6625
6630
 
6631
+
6626
6632
 
6627
6633
  static isAPrivateIp(ip ) {
6628
6634
  const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
@@ -6688,6 +6694,7 @@ class WebRTCClient extends Emitter {
6688
6694
  this.ON_ERROR = ON_ERROR;
6689
6695
  this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
6690
6696
  this.ON_NETWORK_STATS = ON_NETWORK_STATS$1;
6697
+ this.ON_DISCONNECTED = ON_DISCONNECTED$1;
6691
6698
  }
6692
6699
 
6693
6700
  configureMedia(media ) {
@@ -7289,7 +7296,7 @@ class WebRTCClient extends Emitter {
7289
7296
  // We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
7290
7297
  const transceivers = pc.getTransceivers();
7291
7298
  const transceiverIdx = lastIndexOf(transceivers, transceiver =>
7292
- transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
7299
+ transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
7293
7300
 
7294
7301
  videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
7295
7302
  } else {
@@ -7535,10 +7542,13 @@ class WebRTCClient extends Emitter {
7535
7542
  return null;
7536
7543
  }
7537
7544
 
7538
- // let's update the local value
7539
- if (this.audio && this.audio.deviceId) {
7540
- // $FlowFixMe
7541
- this.audio.deviceId.exact = id;
7545
+ // let's update the local audio value
7546
+ if (this.audio) {
7547
+ this.audio = {
7548
+ deviceId: {
7549
+ exact: id,
7550
+ },
7551
+ };
7542
7552
  }
7543
7553
 
7544
7554
  if (session) {
@@ -7551,6 +7561,9 @@ class WebRTCClient extends Emitter {
7551
7561
  const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
7552
7562
 
7553
7563
  if (sender) {
7564
+ if (sender.track) {
7565
+ audioTrack.enabled = sender.track.enabled;
7566
+ }
7554
7567
  sender.replaceTrack(audioTrack);
7555
7568
  }
7556
7569
 
@@ -7575,7 +7588,7 @@ class WebRTCClient extends Emitter {
7575
7588
  return null;
7576
7589
  }
7577
7590
 
7578
- // let's update the local value
7591
+ // let's update the local video value
7579
7592
  if (this.video) {
7580
7593
  this.video = {
7581
7594
  deviceId: {
@@ -7610,12 +7623,21 @@ class WebRTCClient extends Emitter {
7610
7623
  return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
7611
7624
  const videoTrack = stream.getVideoTracks()[0];
7612
7625
  let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
7626
+ let wasTrackEnabled = false;
7613
7627
  if (!sender) {
7614
7628
  sender = pc && pc.getSenders().find(s => !s.track);
7615
7629
  }
7616
7630
 
7617
7631
  if (sender) {
7618
- sender.replaceTrack(videoTrack);
7632
+ // No video track means video not enabled
7633
+ wasTrackEnabled = sender.track ? sender.track.enabled : false;
7634
+ videoTrack.enabled = wasTrackEnabled;
7635
+
7636
+ if (!wasTrackEnabled) {
7637
+ videoTrack.stop();
7638
+ }
7639
+
7640
+ sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
7619
7641
  }
7620
7642
 
7621
7643
  // let's update the local stream
@@ -8299,6 +8321,7 @@ class WebRTCClient extends Emitter {
8299
8321
 
8300
8322
  this.updateRemoteStream(this.getSipSessionId(session));
8301
8323
 
8324
+ const pc = session.sessionDescriptionHandler.peerConnection;
8302
8325
  const onTrack = (event ) => {
8303
8326
  const isAudioOnly = this._isAudioOnly(session);
8304
8327
  const { kind, label, readyState, id, muted } = event.track;
@@ -8318,6 +8341,12 @@ class WebRTCClient extends Emitter {
8318
8341
 
8319
8342
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
8320
8343
 
8344
+ pc.oniceconnectionstatechange = () => {
8345
+ if (pc.iceConnectionState === 'disconnected') {
8346
+ this.eventEmitter.emit(ON_DISCONNECTED$1);
8347
+ }
8348
+ };
8349
+
8321
8350
  if (withEvent) {
8322
8351
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
8323
8352
  }
@@ -8529,25 +8558,33 @@ class WebRTCClient extends Emitter {
8529
8558
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
8530
8559
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
8531
8560
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
8561
+ const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
8562
+ const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
8532
8563
  let audioBytesSent = 0;
8533
8564
  let audioBytesReceived = 0;
8534
8565
  let videoBytesSent = 0;
8535
8566
  let videoBytesReceived = 0;
8567
+ let transportSent = 0;
8568
+ let transportReceived = 0;
8569
+ let packetsLost = 0;
8536
8570
 
8537
8571
  stats.forEach(report => {
8538
8572
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
8573
+ audioBytesSent += report.bytesSent + report.headerBytesSent;
8574
+ }
8575
+ if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
8539
8576
  audioBytesSent += report.bytesSent;
8540
8577
  }
8541
8578
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
8542
- videoBytesSent += report.bytesSent;
8579
+ videoBytesSent += report.bytesSent + report.headerBytesSent;
8543
8580
  }
8544
8581
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
8545
- networkStats.packetsLost = report.packetsLost;
8582
+ packetsLost += report.packetsLost;
8546
8583
  networkStats.packetsReceived = report.packetsReceived;
8547
- audioBytesReceived += report.bytesReceived;
8584
+ audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
8548
8585
  }
8549
8586
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
8550
- videoBytesReceived += report.bytesReceived;
8587
+ videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
8551
8588
  }
8552
8589
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
8553
8590
  if ('framesPerSecond' in report) {
@@ -8559,19 +8596,32 @@ class WebRTCClient extends Emitter {
8559
8596
  }
8560
8597
  }
8561
8598
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
8599
+ packetsLost += report.packetsLost;
8562
8600
  networkStats.roundTripTime = report.roundTripTime;
8563
8601
  networkStats.jitter = report.jitter;
8564
8602
  }
8603
+ if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
8604
+ packetsLost += report.packetsLost;
8605
+ }
8606
+ if (report.type === 'transport') {
8607
+ transportSent += report.bytesSent;
8608
+ transportReceived += report.bytesReceived;
8609
+ }
8565
8610
  });
8566
8611
 
8612
+ networkStats.packetsLost = packetsLost;
8567
8613
  networkStats.audioBytesSent = audioBytesSent;
8568
8614
  networkStats.audioBytesReceived = audioBytesReceived;
8569
8615
  networkStats.videoBytesSent = videoBytesSent;
8570
8616
  networkStats.videoBytesReceived = videoBytesReceived;
8617
+ networkStats.transportSent = transportSent;
8618
+ networkStats.transportReceived = transportReceived;
8571
8619
 
8572
- networkStats.bandwidth = (networkStats.audioBytesSent - lastAudioSent)
8573
- + (networkStats.videoBytesSent - lastVideoSent) + (networkStats.audioBytesReceived - lastAudioReceived)
8574
- + (networkStats.videoBytesReceived - lastVideoReceived);
8620
+ const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
8621
+ + (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
8622
+ + (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
8623
+
8624
+ networkStats.bandwidth = bandwidth;
8575
8625
 
8576
8626
  this.eventEmitter.emit(ON_NETWORK_STATS$1, session, networkStats, this.sessionNetworkStats[sessionId]);
8577
8627
  this.sessionNetworkStats[sessionId].push(networkStats);
@@ -8620,6 +8670,7 @@ const ON_MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
8620
8670
  const ON_NETWORK_STATS = 'onNetworkStats';
8621
8671
  const ON_CHAT = 'phone/ON_CHAT';
8622
8672
  const ON_SIGNAL = 'phone/ON_SIGNAL';
8673
+ const ON_DISCONNECTED = 'onDisconnected';
8623
8674
 
8624
8675
  const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
8625
8676
  const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
@@ -8659,6 +8710,7 @@ const events = [
8659
8710
  ON_CHAT,
8660
8711
  ON_SIGNAL,
8661
8712
  ON_NETWORK_STATS,
8713
+ ON_DISCONNECTED,
8662
8714
  ];
8663
8715
 
8664
8716
  const logger$7 = IssueReporter$1.loggerFor('webrtc-phone');
@@ -10011,6 +10063,11 @@ class WebRTCPhone extends Emitter {
10011
10063
  this.eventEmitter.emit(ON_UNREGISTERED);
10012
10064
  });
10013
10065
 
10066
+ this.client.on(this.client.ON_DISCONNECTED, () => {
10067
+ logger$7.info('WebRTC disconnected');
10068
+ this.eventEmitter.emit(ON_DISCONNECTED);
10069
+ });
10070
+
10014
10071
  this.client.on(this.client.REGISTERED, () => {
10015
10072
  logger$7.info('WebRTC registered', {
10016
10073
  shouldSendReinvite: this.shouldSendReinvite,
@@ -10267,6 +10324,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10267
10324
  ON_NETWORK_STATS: ON_NETWORK_STATS,
10268
10325
  ON_CHAT: ON_CHAT,
10269
10326
  ON_SIGNAL: ON_SIGNAL,
10327
+ ON_DISCONNECTED: ON_DISCONNECTED,
10270
10328
  MESSAGE_TYPE_CHAT: MESSAGE_TYPE_CHAT,
10271
10329
  MESSAGE_TYPE_SIGNAL: MESSAGE_TYPE_SIGNAL,
10272
10330
  events: events,