@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
@@ -410,7 +410,7 @@ class IssueReporter {
410
410
  payload._retry = retry + 1;
411
411
  }
412
412
 
413
- this._sendDebugToGrafana(body, retry + 1);
413
+ this._sendDebugToGrafana(payload, retry + 1);
414
414
  }, 5000 + retry * 1000);
415
415
  });
416
416
  }
@@ -2613,7 +2613,8 @@ class ExternalApp {
2613
2613
 
2614
2614
 
2615
2615
 
2616
-
2616
+
2617
+
2617
2618
 
2618
2619
 
2619
2620
  class Meeting {
@@ -2625,6 +2626,7 @@ class Meeting {
2625
2626
 
2626
2627
 
2627
2628
 
2629
+
2628
2630
 
2629
2631
 
2630
2632
  static parse(plain ) {
@@ -2636,6 +2638,7 @@ class Meeting {
2636
2638
  port: plain.port,
2637
2639
  uuid: plain.uuid,
2638
2640
  number: plain.number,
2641
+ persistent: plain.persistent,
2639
2642
  });
2640
2643
  }
2641
2644
 
@@ -2643,7 +2646,7 @@ class Meeting {
2643
2646
  return newFrom(meeting, Meeting);
2644
2647
  }
2645
2648
 
2646
- constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
2649
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
2647
2650
  this.guestSipAuthorization = guestSipAuthorization;
2648
2651
  this.uri = uri;
2649
2652
  this.name = name;
@@ -2651,6 +2654,7 @@ class Meeting {
2651
2654
  this.port = port;
2652
2655
  this.uuid = uuid;
2653
2656
  this.number = number;
2657
+ this.persistent = persistent;
2654
2658
 
2655
2659
  // Useful to compare instead of instanceof with minified code
2656
2660
  this.type = 'Meeting';
@@ -3240,7 +3244,7 @@ class Recording {
3240
3244
 
3241
3245
 
3242
3246
 
3243
- static parseMany(recordings ) {
3247
+ static parseMany(recordings = []) {
3244
3248
  return recordings.map(item => Recording.parse(item));
3245
3249
  }
3246
3250
 
@@ -3366,7 +3370,7 @@ class CallLog {
3366
3370
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3367
3371
  start: moment__default['default'](plain.start).toDate(),
3368
3372
  end: plain.end ? moment__default['default'](plain.end).toDate() : null,
3369
- recordings: Recording.parseMany(plain.recordings),
3373
+ recordings: Recording.parseMany(plain.recordings || []),
3370
3374
  });
3371
3375
  }
3372
3376
 
@@ -5881,6 +5885,7 @@ const ON_REINVITE = 'reinvite';
5881
5885
  const ON_ERROR = 'onError';
5882
5886
  const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
5883
5887
  const ON_NETWORK_STATS = 'onNetworkStats';
5888
+ const ON_DISCONNECTED = 'onDisconnected';
5884
5889
  class CanceledCallError extends Error {}
5885
5890
 
5886
5891
  const MAX_REGISTER_TRIES = 10;
@@ -5954,6 +5959,7 @@ class WebRTCClient extends Emitter {
5954
5959
 
5955
5960
 
5956
5961
 
5962
+
5957
5963
 
5958
5964
  static isAPrivateIp(ip ) {
5959
5965
  const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
@@ -6019,6 +6025,7 @@ class WebRTCClient extends Emitter {
6019
6025
  this.ON_ERROR = ON_ERROR;
6020
6026
  this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
6021
6027
  this.ON_NETWORK_STATS = ON_NETWORK_STATS;
6028
+ this.ON_DISCONNECTED = ON_DISCONNECTED;
6022
6029
  }
6023
6030
 
6024
6031
  configureMedia(media ) {
@@ -6620,7 +6627,7 @@ class WebRTCClient extends Emitter {
6620
6627
  // We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
6621
6628
  const transceivers = pc.getTransceivers();
6622
6629
  const transceiverIdx = lastIndexOf(transceivers, transceiver =>
6623
- transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
6630
+ transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
6624
6631
 
6625
6632
  videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
6626
6633
  } else {
@@ -6866,10 +6873,13 @@ class WebRTCClient extends Emitter {
6866
6873
  return null;
6867
6874
  }
6868
6875
 
6869
- // let's update the local value
6870
- if (this.audio && this.audio.deviceId) {
6871
- // $FlowFixMe
6872
- this.audio.deviceId.exact = id;
6876
+ // let's update the local audio value
6877
+ if (this.audio) {
6878
+ this.audio = {
6879
+ deviceId: {
6880
+ exact: id,
6881
+ },
6882
+ };
6873
6883
  }
6874
6884
 
6875
6885
  if (session) {
@@ -6882,6 +6892,9 @@ class WebRTCClient extends Emitter {
6882
6892
  const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
6883
6893
 
6884
6894
  if (sender) {
6895
+ if (sender.track) {
6896
+ audioTrack.enabled = sender.track.enabled;
6897
+ }
6885
6898
  sender.replaceTrack(audioTrack);
6886
6899
  }
6887
6900
 
@@ -6906,7 +6919,7 @@ class WebRTCClient extends Emitter {
6906
6919
  return null;
6907
6920
  }
6908
6921
 
6909
- // let's update the local value
6922
+ // let's update the local video value
6910
6923
  if (this.video) {
6911
6924
  this.video = {
6912
6925
  deviceId: {
@@ -6941,12 +6954,21 @@ class WebRTCClient extends Emitter {
6941
6954
  return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
6942
6955
  const videoTrack = stream.getVideoTracks()[0];
6943
6956
  let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
6957
+ let wasTrackEnabled = false;
6944
6958
  if (!sender) {
6945
6959
  sender = pc && pc.getSenders().find(s => !s.track);
6946
6960
  }
6947
6961
 
6948
6962
  if (sender) {
6949
- sender.replaceTrack(videoTrack);
6963
+ // No video track means video not enabled
6964
+ wasTrackEnabled = sender.track ? sender.track.enabled : false;
6965
+ videoTrack.enabled = wasTrackEnabled;
6966
+
6967
+ if (!wasTrackEnabled) {
6968
+ videoTrack.stop();
6969
+ }
6970
+
6971
+ sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
6950
6972
  }
6951
6973
 
6952
6974
  // let's update the local stream
@@ -7630,6 +7652,7 @@ class WebRTCClient extends Emitter {
7630
7652
 
7631
7653
  this.updateRemoteStream(this.getSipSessionId(session));
7632
7654
 
7655
+ const pc = session.sessionDescriptionHandler.peerConnection;
7633
7656
  const onTrack = (event ) => {
7634
7657
  const isAudioOnly = this._isAudioOnly(session);
7635
7658
  const { kind, label, readyState, id, muted } = event.track;
@@ -7649,6 +7672,12 @@ class WebRTCClient extends Emitter {
7649
7672
 
7650
7673
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
7651
7674
 
7675
+ pc.oniceconnectionstatechange = () => {
7676
+ if (pc.iceConnectionState === 'disconnected') {
7677
+ this.eventEmitter.emit(ON_DISCONNECTED);
7678
+ }
7679
+ };
7680
+
7652
7681
  if (withEvent) {
7653
7682
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
7654
7683
  }
@@ -7860,25 +7889,33 @@ class WebRTCClient extends Emitter {
7860
7889
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
7861
7890
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
7862
7891
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
7892
+ const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
7893
+ const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
7863
7894
  let audioBytesSent = 0;
7864
7895
  let audioBytesReceived = 0;
7865
7896
  let videoBytesSent = 0;
7866
7897
  let videoBytesReceived = 0;
7898
+ let transportSent = 0;
7899
+ let transportReceived = 0;
7900
+ let packetsLost = 0;
7867
7901
 
7868
7902
  stats.forEach(report => {
7869
7903
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
7904
+ audioBytesSent += report.bytesSent + report.headerBytesSent;
7905
+ }
7906
+ if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
7870
7907
  audioBytesSent += report.bytesSent;
7871
7908
  }
7872
7909
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7873
- videoBytesSent += report.bytesSent;
7910
+ videoBytesSent += report.bytesSent + report.headerBytesSent;
7874
7911
  }
7875
7912
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
7876
- networkStats.packetsLost = report.packetsLost;
7913
+ packetsLost += report.packetsLost;
7877
7914
  networkStats.packetsReceived = report.packetsReceived;
7878
- audioBytesReceived += report.bytesReceived;
7915
+ audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
7879
7916
  }
7880
7917
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
7881
- videoBytesReceived += report.bytesReceived;
7918
+ videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
7882
7919
  }
7883
7920
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7884
7921
  if ('framesPerSecond' in report) {
@@ -7890,19 +7927,32 @@ class WebRTCClient extends Emitter {
7890
7927
  }
7891
7928
  }
7892
7929
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
7930
+ packetsLost += report.packetsLost;
7893
7931
  networkStats.roundTripTime = report.roundTripTime;
7894
7932
  networkStats.jitter = report.jitter;
7895
7933
  }
7934
+ if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
7935
+ packetsLost += report.packetsLost;
7936
+ }
7937
+ if (report.type === 'transport') {
7938
+ transportSent += report.bytesSent;
7939
+ transportReceived += report.bytesReceived;
7940
+ }
7896
7941
  });
7897
7942
 
7943
+ networkStats.packetsLost = packetsLost;
7898
7944
  networkStats.audioBytesSent = audioBytesSent;
7899
7945
  networkStats.audioBytesReceived = audioBytesReceived;
7900
7946
  networkStats.videoBytesSent = videoBytesSent;
7901
7947
  networkStats.videoBytesReceived = videoBytesReceived;
7948
+ networkStats.transportSent = transportSent;
7949
+ networkStats.transportReceived = transportReceived;
7950
+
7951
+ const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
7952
+ + (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
7953
+ + (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
7902
7954
 
7903
- networkStats.bandwidth = (networkStats.audioBytesSent - lastAudioSent)
7904
- + (networkStats.videoBytesSent - lastVideoSent) + (networkStats.audioBytesReceived - lastAudioReceived)
7905
- + (networkStats.videoBytesReceived - lastVideoReceived);
7955
+ networkStats.bandwidth = bandwidth;
7906
7956
 
7907
7957
  this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
7908
7958
  this.sessionNetworkStats[sessionId].push(networkStats);
@@ -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
  }
@@ -673,7 +673,7 @@ class IssueReporter {
673
673
  payload._retry = retry + 1;
674
674
  }
675
675
 
676
- this._sendDebugToGrafana(body, retry + 1);
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 && this.audio.deviceId) {
6287
- // $FlowFixMe
6288
- this.audio.deviceId.exact = id;
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
- sender.replaceTrack(videoTrack);
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
  }
@@ -7276,25 +7305,33 @@ class WebRTCClient extends Emitter {
7276
7305
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
7277
7306
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
7278
7307
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
7308
+ const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
7309
+ const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
7279
7310
  let audioBytesSent = 0;
7280
7311
  let audioBytesReceived = 0;
7281
7312
  let videoBytesSent = 0;
7282
7313
  let videoBytesReceived = 0;
7314
+ let transportSent = 0;
7315
+ let transportReceived = 0;
7316
+ let packetsLost = 0;
7283
7317
 
7284
7318
  stats.forEach(report => {
7285
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') {
7286
7323
  audioBytesSent += report.bytesSent;
7287
7324
  }
7288
7325
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7289
- videoBytesSent += report.bytesSent;
7326
+ videoBytesSent += report.bytesSent + report.headerBytesSent;
7290
7327
  }
7291
7328
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
7292
- networkStats.packetsLost = report.packetsLost;
7329
+ packetsLost += report.packetsLost;
7293
7330
  networkStats.packetsReceived = report.packetsReceived;
7294
- audioBytesReceived += report.bytesReceived;
7331
+ audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
7295
7332
  }
7296
7333
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
7297
- videoBytesReceived += report.bytesReceived;
7334
+ videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
7298
7335
  }
7299
7336
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7300
7337
  if ('framesPerSecond' in report) {
@@ -7306,19 +7343,32 @@ class WebRTCClient extends Emitter {
7306
7343
  }
7307
7344
  }
7308
7345
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
7346
+ packetsLost += report.packetsLost;
7309
7347
  networkStats.roundTripTime = report.roundTripTime;
7310
7348
  networkStats.jitter = report.jitter;
7311
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;
7356
+ }
7312
7357
  });
7313
7358
 
7359
+ networkStats.packetsLost = packetsLost;
7314
7360
  networkStats.audioBytesSent = audioBytesSent;
7315
7361
  networkStats.audioBytesReceived = audioBytesReceived;
7316
7362
  networkStats.videoBytesSent = videoBytesSent;
7317
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);
7318
7370
 
7319
- networkStats.bandwidth = (networkStats.audioBytesSent - lastAudioSent)
7320
- + (networkStats.videoBytesSent - lastVideoSent) + (networkStats.audioBytesReceived - lastAudioReceived)
7321
- + (networkStats.videoBytesReceived - lastVideoReceived);
7371
+ networkStats.bandwidth = bandwidth;
7322
7372
 
7323
7373
  this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
7324
7374
  this.sessionNetworkStats[sessionId].push(networkStats);