@wazo/sdk 0.37.4 → 0.37.8

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 (45) hide show
  1. package/dist/wazo-sdk.js +2 -2
  2. package/esm/__tests__/web-rtc-client.test.js +4 -0
  3. package/esm/checker/Checker.js +4 -0
  4. package/esm/checker/checks/index.js +4 -0
  5. package/esm/checker/checks/webrtc-transport.js +4 -0
  6. package/esm/checker/checks/webrtc.js +4 -0
  7. package/esm/domain/Phone/WebRTCPhone.js +17 -4
  8. package/esm/index.js +23 -5
  9. package/esm/simple/Auth.js +23 -5
  10. package/esm/simple/Configuration.js +23 -5
  11. package/esm/simple/Phone.js +23 -5
  12. package/esm/simple/index.js +23 -5
  13. package/esm/simple/room/LocalParticipant.js +23 -5
  14. package/esm/simple/room/Participant.js +23 -5
  15. package/esm/simple/room/RemoteParticipant.js +23 -5
  16. package/esm/simple/room/Room.js +23 -5
  17. package/esm/simple/room/SipRoom.js +23 -5
  18. package/esm/simple/room/Stream.js +23 -5
  19. package/esm/simple/room/__tests__/RemoteParticipant.test.js +23 -5
  20. package/esm/simple/utils.js +23 -5
  21. package/esm/web-rtc-client.js +4 -0
  22. package/lib/__tests__/web-rtc-client.test.js +4 -0
  23. package/lib/checker/Checker.js +4 -0
  24. package/lib/checker/checks/index.js +4 -0
  25. package/lib/checker/checks/webrtc-transport.js +4 -0
  26. package/lib/checker/checks/webrtc.js +4 -0
  27. package/lib/domain/Phone/WebRTCPhone.js +17 -4
  28. package/lib/index.js +23 -5
  29. package/lib/simple/Auth.js +23 -5
  30. package/lib/simple/Configuration.js +23 -5
  31. package/lib/simple/Phone.js +23 -5
  32. package/lib/simple/index.js +23 -5
  33. package/lib/simple/room/LocalParticipant.js +23 -5
  34. package/lib/simple/room/Participant.js +23 -5
  35. package/lib/simple/room/RemoteParticipant.js +23 -5
  36. package/lib/simple/room/Room.js +23 -5
  37. package/lib/simple/room/SipRoom.js +23 -5
  38. package/lib/simple/room/Stream.js +23 -5
  39. package/lib/simple/room/__tests__/RemoteParticipant.test.js +23 -5
  40. package/lib/simple/utils.js +23 -5
  41. package/lib/web-rtc-client.js +4 -0
  42. package/package.json +1 -1
  43. package/src/domain/Phone/WebRTCPhone.js +17 -4
  44. package/src/simple/room/Room.js +2 -1
  45. package/src/web-rtc-client.js +4 -0
@@ -5788,6 +5788,8 @@ class WebRTCClient extends Emitter {
5788
5788
  }
5789
5789
  options.sessionDescriptionHandlerOptions = {
5790
5790
  constraints: options.constraints,
5791
+ hold: true,
5792
+ conference: isConference,
5791
5793
  };
5792
5794
 
5793
5795
  // Send re-INVITE
@@ -5830,6 +5832,8 @@ class WebRTCClient extends Emitter {
5830
5832
  }
5831
5833
  options.sessionDescriptionHandlerOptions = {
5832
5834
  constraints: options.constraints,
5835
+ hold: false,
5836
+ conference: isConference,
5833
5837
  };
5834
5838
 
5835
5839
  // Send re-INVITE
@@ -6371,6 +6371,8 @@ class WebRTCClient extends Emitter {
6371
6371
  }
6372
6372
  options.sessionDescriptionHandlerOptions = {
6373
6373
  constraints: options.constraints,
6374
+ hold: true,
6375
+ conference: isConference,
6374
6376
  };
6375
6377
 
6376
6378
  // Send re-INVITE
@@ -6413,6 +6415,8 @@ class WebRTCClient extends Emitter {
6413
6415
  }
6414
6416
  options.sessionDescriptionHandlerOptions = {
6415
6417
  constraints: options.constraints,
6418
+ hold: false,
6419
+ conference: isConference,
6416
6420
  };
6417
6421
 
6418
6422
  // Send re-INVITE
@@ -6371,6 +6371,8 @@ class WebRTCClient extends Emitter {
6371
6371
  }
6372
6372
  options.sessionDescriptionHandlerOptions = {
6373
6373
  constraints: options.constraints,
6374
+ hold: true,
6375
+ conference: isConference,
6374
6376
  };
6375
6377
 
6376
6378
  // Send re-INVITE
@@ -6413,6 +6415,8 @@ class WebRTCClient extends Emitter {
6413
6415
  }
6414
6416
  options.sessionDescriptionHandlerOptions = {
6415
6417
  constraints: options.constraints,
6418
+ hold: false,
6419
+ conference: isConference,
6416
6420
  };
6417
6421
 
6418
6422
  // Send re-INVITE
@@ -5788,6 +5788,8 @@ class WebRTCClient extends Emitter {
5788
5788
  }
5789
5789
  options.sessionDescriptionHandlerOptions = {
5790
5790
  constraints: options.constraints,
5791
+ hold: true,
5792
+ conference: isConference,
5791
5793
  };
5792
5794
 
5793
5795
  // Send re-INVITE
@@ -5830,6 +5832,8 @@ class WebRTCClient extends Emitter {
5830
5832
  }
5831
5833
  options.sessionDescriptionHandlerOptions = {
5832
5834
  constraints: options.constraints,
5835
+ hold: false,
5836
+ conference: isConference,
5833
5837
  };
5834
5838
 
5835
5839
  // Send re-INVITE
@@ -5788,6 +5788,8 @@ class WebRTCClient extends Emitter {
5788
5788
  }
5789
5789
  options.sessionDescriptionHandlerOptions = {
5790
5790
  constraints: options.constraints,
5791
+ hold: true,
5792
+ conference: isConference,
5791
5793
  };
5792
5794
 
5793
5795
  // Send re-INVITE
@@ -5830,6 +5832,8 @@ class WebRTCClient extends Emitter {
5830
5832
  }
5831
5833
  options.sessionDescriptionHandlerOptions = {
5832
5834
  constraints: options.constraints,
5835
+ hold: false,
5836
+ conference: isConference,
5833
5837
  };
5834
5838
 
5835
5839
  // Send re-INVITE
@@ -1041,7 +1041,7 @@ class WebRTCPhone extends Emitter {
1041
1041
  return this.client.onDisconnect();
1042
1042
  }
1043
1043
 
1044
- _downgradeToAudio(callSession ) {
1044
+ _downgradeToAudio(callSession , withMessage = true) {
1045
1045
  const sipSession = this.findSipSession(callSession);
1046
1046
  if (!sipSession) {
1047
1047
  return false;
@@ -1068,7 +1068,9 @@ class WebRTCPhone extends Emitter {
1068
1068
  localStream.removeTrack(videoTrack);
1069
1069
  });
1070
1070
 
1071
- this._sendReinviteMessage(callSession, false);
1071
+ if (withMessage) {
1072
+ this._sendReinviteMessage(callSession, false);
1073
+ }
1072
1074
 
1073
1075
  return true;
1074
1076
  }
@@ -1087,9 +1089,9 @@ class WebRTCPhone extends Emitter {
1087
1089
 
1088
1090
  // Check if a video sender already exists
1089
1091
  let videoSender;
1092
+ const videoTransceiver = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
1090
1093
  if (isConference) {
1091
- const trans = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
1092
- videoSender = trans ? trans.sender : null;
1094
+ videoSender = videoTransceiver ? videoTransceiver.sender : null;
1093
1095
  } else {
1094
1096
  videoSender = pc.getSenders().find(sender => sender.track === null);
1095
1097
  }
@@ -1119,6 +1121,11 @@ class WebRTCPhone extends Emitter {
1119
1121
  videoSender.replaceTrack(videoTrack);
1120
1122
  }
1121
1123
 
1124
+ // Put back last direction (was set to `recvonly` when downgrading)
1125
+ if (videoTransceiver && videoTransceiver.currentDirection !== videoTransceiver.direction) {
1126
+ videoTransceiver.direction = videoTransceiver.currentDirection;
1127
+ }
1128
+
1122
1129
  this.client.setLocalMediaStream(this.getSipSessionId(sipSession), newStream);
1123
1130
  this._sendReinviteMessage(callSession, true);
1124
1131
 
@@ -1281,6 +1288,12 @@ class WebRTCPhone extends Emitter {
1281
1288
  // We have to downgrade to audio.
1282
1289
  const screenshareStopped = this.currentScreenShare.sender && this.currentScreenShare.hadVideo;
1283
1290
  const constraints = { audio: false, video: screenshareStopped };
1291
+ if (!conference) {
1292
+ // We have to remove the video sender to be able to re-upgrade to video in `sendReinvite` below
1293
+ this._downgradeToAudio(targetCallSession, false);
1294
+ // Wait for the track to be removed, unless the video sender won't have a null track in `_upgradeToVideo`.
1295
+ await new Promise(resolve => setTimeout(resolve, 500));
1296
+ }
1284
1297
  reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
1285
1298
  }
1286
1299
  } catch (e) {
package/esm/index.js CHANGED
@@ -6597,6 +6597,8 @@ class WebRTCClient extends Emitter {
6597
6597
  }
6598
6598
  options.sessionDescriptionHandlerOptions = {
6599
6599
  constraints: options.constraints,
6600
+ hold: true,
6601
+ conference: isConference,
6600
6602
  };
6601
6603
 
6602
6604
  // Send re-INVITE
@@ -6639,6 +6641,8 @@ class WebRTCClient extends Emitter {
6639
6641
  }
6640
6642
  options.sessionDescriptionHandlerOptions = {
6641
6643
  constraints: options.constraints,
6644
+ hold: false,
6645
+ conference: isConference,
6642
6646
  };
6643
6647
 
6644
6648
  // Send re-INVITE
@@ -8858,7 +8862,7 @@ class WebRTCPhone extends Emitter {
8858
8862
  return this.client.onDisconnect();
8859
8863
  }
8860
8864
 
8861
- _downgradeToAudio(callSession ) {
8865
+ _downgradeToAudio(callSession , withMessage = true) {
8862
8866
  const sipSession = this.findSipSession(callSession);
8863
8867
  if (!sipSession) {
8864
8868
  return false;
@@ -8885,7 +8889,9 @@ class WebRTCPhone extends Emitter {
8885
8889
  localStream.removeTrack(videoTrack);
8886
8890
  });
8887
8891
 
8888
- this._sendReinviteMessage(callSession, false);
8892
+ if (withMessage) {
8893
+ this._sendReinviteMessage(callSession, false);
8894
+ }
8889
8895
 
8890
8896
  return true;
8891
8897
  }
@@ -8904,9 +8910,9 @@ class WebRTCPhone extends Emitter {
8904
8910
 
8905
8911
  // Check if a video sender already exists
8906
8912
  let videoSender;
8913
+ const videoTransceiver = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
8907
8914
  if (isConference) {
8908
- const trans = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
8909
- videoSender = trans ? trans.sender : null;
8915
+ videoSender = videoTransceiver ? videoTransceiver.sender : null;
8910
8916
  } else {
8911
8917
  videoSender = pc.getSenders().find(sender => sender.track === null);
8912
8918
  }
@@ -8936,6 +8942,11 @@ class WebRTCPhone extends Emitter {
8936
8942
  videoSender.replaceTrack(videoTrack);
8937
8943
  }
8938
8944
 
8945
+ // Put back last direction (was set to `recvonly` when downgrading)
8946
+ if (videoTransceiver && videoTransceiver.currentDirection !== videoTransceiver.direction) {
8947
+ videoTransceiver.direction = videoTransceiver.currentDirection;
8948
+ }
8949
+
8939
8950
  this.client.setLocalMediaStream(this.getSipSessionId(sipSession), newStream);
8940
8951
  this._sendReinviteMessage(callSession, true);
8941
8952
 
@@ -9098,6 +9109,12 @@ class WebRTCPhone extends Emitter {
9098
9109
  // We have to downgrade to audio.
9099
9110
  const screenshareStopped = this.currentScreenShare.sender && this.currentScreenShare.hadVideo;
9100
9111
  const constraints = { audio: false, video: screenshareStopped };
9112
+ if (!conference) {
9113
+ // We have to remove the video sender to be able to re-upgrade to video in `sendReinvite` below
9114
+ this._downgradeToAudio(targetCallSession, false);
9115
+ // Wait for the track to be removed, unless the video sender won't have a null track in `_upgradeToVideo`.
9116
+ await new Promise(resolve => setTimeout(resolve, 500));
9117
+ }
9101
9118
  reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
9102
9119
  }
9103
9120
  } catch (e) {
@@ -12781,7 +12798,8 @@ class Room extends Emitter {
12781
12798
  }
12782
12799
 
12783
12800
  // Find in all the streams by streamId (used on FF where we can't map by trackId)
12784
- const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) => stream.id === streamId);
12801
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
12802
+ stream && stream.id === streamId);
12785
12803
  return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
12786
12804
  }
12787
12805
 
@@ -6771,6 +6771,8 @@ class WebRTCClient extends Emitter {
6771
6771
  }
6772
6772
  options.sessionDescriptionHandlerOptions = {
6773
6773
  constraints: options.constraints,
6774
+ hold: true,
6775
+ conference: isConference,
6774
6776
  };
6775
6777
 
6776
6778
  // Send re-INVITE
@@ -6813,6 +6815,8 @@ class WebRTCClient extends Emitter {
6813
6815
  }
6814
6816
  options.sessionDescriptionHandlerOptions = {
6815
6817
  constraints: options.constraints,
6818
+ hold: false,
6819
+ conference: isConference,
6816
6820
  };
6817
6821
 
6818
6822
  // Send re-INVITE
@@ -8142,7 +8146,7 @@ class WebRTCPhone extends Emitter {
8142
8146
  return this.client.onDisconnect();
8143
8147
  }
8144
8148
 
8145
- _downgradeToAudio(callSession ) {
8149
+ _downgradeToAudio(callSession , withMessage = true) {
8146
8150
  const sipSession = this.findSipSession(callSession);
8147
8151
  if (!sipSession) {
8148
8152
  return false;
@@ -8169,7 +8173,9 @@ class WebRTCPhone extends Emitter {
8169
8173
  localStream.removeTrack(videoTrack);
8170
8174
  });
8171
8175
 
8172
- this._sendReinviteMessage(callSession, false);
8176
+ if (withMessage) {
8177
+ this._sendReinviteMessage(callSession, false);
8178
+ }
8173
8179
 
8174
8180
  return true;
8175
8181
  }
@@ -8188,9 +8194,9 @@ class WebRTCPhone extends Emitter {
8188
8194
 
8189
8195
  // Check if a video sender already exists
8190
8196
  let videoSender;
8197
+ const videoTransceiver = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
8191
8198
  if (isConference) {
8192
- const trans = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
8193
- videoSender = trans ? trans.sender : null;
8199
+ videoSender = videoTransceiver ? videoTransceiver.sender : null;
8194
8200
  } else {
8195
8201
  videoSender = pc.getSenders().find(sender => sender.track === null);
8196
8202
  }
@@ -8220,6 +8226,11 @@ class WebRTCPhone extends Emitter {
8220
8226
  videoSender.replaceTrack(videoTrack);
8221
8227
  }
8222
8228
 
8229
+ // Put back last direction (was set to `recvonly` when downgrading)
8230
+ if (videoTransceiver && videoTransceiver.currentDirection !== videoTransceiver.direction) {
8231
+ videoTransceiver.direction = videoTransceiver.currentDirection;
8232
+ }
8233
+
8223
8234
  this.client.setLocalMediaStream(this.getSipSessionId(sipSession), newStream);
8224
8235
  this._sendReinviteMessage(callSession, true);
8225
8236
 
@@ -8382,6 +8393,12 @@ class WebRTCPhone extends Emitter {
8382
8393
  // We have to downgrade to audio.
8383
8394
  const screenshareStopped = this.currentScreenShare.sender && this.currentScreenShare.hadVideo;
8384
8395
  const constraints = { audio: false, video: screenshareStopped };
8396
+ if (!conference) {
8397
+ // We have to remove the video sender to be able to re-upgrade to video in `sendReinvite` below
8398
+ this._downgradeToAudio(targetCallSession, false);
8399
+ // Wait for the track to be removed, unless the video sender won't have a null track in `_upgradeToVideo`.
8400
+ await new Promise(resolve => setTimeout(resolve, 500));
8401
+ }
8385
8402
  reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
8386
8403
  }
8387
8404
  } catch (e) {
@@ -11544,7 +11561,8 @@ class Room$1 extends Emitter {
11544
11561
  }
11545
11562
 
11546
11563
  // Find in all the streams by streamId (used on FF where we can't map by trackId)
11547
- const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) => stream.id === streamId);
11564
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
11565
+ stream && stream.id === streamId);
11548
11566
  return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
11549
11567
  }
11550
11568
 
@@ -6771,6 +6771,8 @@ class WebRTCClient extends Emitter {
6771
6771
  }
6772
6772
  options.sessionDescriptionHandlerOptions = {
6773
6773
  constraints: options.constraints,
6774
+ hold: true,
6775
+ conference: isConference,
6774
6776
  };
6775
6777
 
6776
6778
  // Send re-INVITE
@@ -6813,6 +6815,8 @@ class WebRTCClient extends Emitter {
6813
6815
  }
6814
6816
  options.sessionDescriptionHandlerOptions = {
6815
6817
  constraints: options.constraints,
6818
+ hold: false,
6819
+ conference: isConference,
6816
6820
  };
6817
6821
 
6818
6822
  // Send re-INVITE
@@ -8142,7 +8146,7 @@ class WebRTCPhone extends Emitter {
8142
8146
  return this.client.onDisconnect();
8143
8147
  }
8144
8148
 
8145
- _downgradeToAudio(callSession ) {
8149
+ _downgradeToAudio(callSession , withMessage = true) {
8146
8150
  const sipSession = this.findSipSession(callSession);
8147
8151
  if (!sipSession) {
8148
8152
  return false;
@@ -8169,7 +8173,9 @@ class WebRTCPhone extends Emitter {
8169
8173
  localStream.removeTrack(videoTrack);
8170
8174
  });
8171
8175
 
8172
- this._sendReinviteMessage(callSession, false);
8176
+ if (withMessage) {
8177
+ this._sendReinviteMessage(callSession, false);
8178
+ }
8173
8179
 
8174
8180
  return true;
8175
8181
  }
@@ -8188,9 +8194,9 @@ class WebRTCPhone extends Emitter {
8188
8194
 
8189
8195
  // Check if a video sender already exists
8190
8196
  let videoSender;
8197
+ const videoTransceiver = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
8191
8198
  if (isConference) {
8192
- const trans = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
8193
- videoSender = trans ? trans.sender : null;
8199
+ videoSender = videoTransceiver ? videoTransceiver.sender : null;
8194
8200
  } else {
8195
8201
  videoSender = pc.getSenders().find(sender => sender.track === null);
8196
8202
  }
@@ -8220,6 +8226,11 @@ class WebRTCPhone extends Emitter {
8220
8226
  videoSender.replaceTrack(videoTrack);
8221
8227
  }
8222
8228
 
8229
+ // Put back last direction (was set to `recvonly` when downgrading)
8230
+ if (videoTransceiver && videoTransceiver.currentDirection !== videoTransceiver.direction) {
8231
+ videoTransceiver.direction = videoTransceiver.currentDirection;
8232
+ }
8233
+
8223
8234
  this.client.setLocalMediaStream(this.getSipSessionId(sipSession), newStream);
8224
8235
  this._sendReinviteMessage(callSession, true);
8225
8236
 
@@ -8382,6 +8393,12 @@ class WebRTCPhone extends Emitter {
8382
8393
  // We have to downgrade to audio.
8383
8394
  const screenshareStopped = this.currentScreenShare.sender && this.currentScreenShare.hadVideo;
8384
8395
  const constraints = { audio: false, video: screenshareStopped };
8396
+ if (!conference) {
8397
+ // We have to remove the video sender to be able to re-upgrade to video in `sendReinvite` below
8398
+ this._downgradeToAudio(targetCallSession, false);
8399
+ // Wait for the track to be removed, unless the video sender won't have a null track in `_upgradeToVideo`.
8400
+ await new Promise(resolve => setTimeout(resolve, 500));
8401
+ }
8385
8402
  reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
8386
8403
  }
8387
8404
  } catch (e) {
@@ -11544,7 +11561,8 @@ class Room$1 extends Emitter {
11544
11561
  }
11545
11562
 
11546
11563
  // Find in all the streams by streamId (used on FF where we can't map by trackId)
11547
- const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) => stream.id === streamId);
11564
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
11565
+ stream && stream.id === streamId);
11548
11566
  return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
11549
11567
  }
11550
11568
 
@@ -6771,6 +6771,8 @@ class WebRTCClient extends Emitter {
6771
6771
  }
6772
6772
  options.sessionDescriptionHandlerOptions = {
6773
6773
  constraints: options.constraints,
6774
+ hold: true,
6775
+ conference: isConference,
6774
6776
  };
6775
6777
 
6776
6778
  // Send re-INVITE
@@ -6813,6 +6815,8 @@ class WebRTCClient extends Emitter {
6813
6815
  }
6814
6816
  options.sessionDescriptionHandlerOptions = {
6815
6817
  constraints: options.constraints,
6818
+ hold: false,
6819
+ conference: isConference,
6816
6820
  };
6817
6821
 
6818
6822
  // Send re-INVITE
@@ -8142,7 +8146,7 @@ class WebRTCPhone extends Emitter {
8142
8146
  return this.client.onDisconnect();
8143
8147
  }
8144
8148
 
8145
- _downgradeToAudio(callSession ) {
8149
+ _downgradeToAudio(callSession , withMessage = true) {
8146
8150
  const sipSession = this.findSipSession(callSession);
8147
8151
  if (!sipSession) {
8148
8152
  return false;
@@ -8169,7 +8173,9 @@ class WebRTCPhone extends Emitter {
8169
8173
  localStream.removeTrack(videoTrack);
8170
8174
  });
8171
8175
 
8172
- this._sendReinviteMessage(callSession, false);
8176
+ if (withMessage) {
8177
+ this._sendReinviteMessage(callSession, false);
8178
+ }
8173
8179
 
8174
8180
  return true;
8175
8181
  }
@@ -8188,9 +8194,9 @@ class WebRTCPhone extends Emitter {
8188
8194
 
8189
8195
  // Check if a video sender already exists
8190
8196
  let videoSender;
8197
+ const videoTransceiver = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
8191
8198
  if (isConference) {
8192
- const trans = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
8193
- videoSender = trans ? trans.sender : null;
8199
+ videoSender = videoTransceiver ? videoTransceiver.sender : null;
8194
8200
  } else {
8195
8201
  videoSender = pc.getSenders().find(sender => sender.track === null);
8196
8202
  }
@@ -8220,6 +8226,11 @@ class WebRTCPhone extends Emitter {
8220
8226
  videoSender.replaceTrack(videoTrack);
8221
8227
  }
8222
8228
 
8229
+ // Put back last direction (was set to `recvonly` when downgrading)
8230
+ if (videoTransceiver && videoTransceiver.currentDirection !== videoTransceiver.direction) {
8231
+ videoTransceiver.direction = videoTransceiver.currentDirection;
8232
+ }
8233
+
8223
8234
  this.client.setLocalMediaStream(this.getSipSessionId(sipSession), newStream);
8224
8235
  this._sendReinviteMessage(callSession, true);
8225
8236
 
@@ -8382,6 +8393,12 @@ class WebRTCPhone extends Emitter {
8382
8393
  // We have to downgrade to audio.
8383
8394
  const screenshareStopped = this.currentScreenShare.sender && this.currentScreenShare.hadVideo;
8384
8395
  const constraints = { audio: false, video: screenshareStopped };
8396
+ if (!conference) {
8397
+ // We have to remove the video sender to be able to re-upgrade to video in `sendReinvite` below
8398
+ this._downgradeToAudio(targetCallSession, false);
8399
+ // Wait for the track to be removed, unless the video sender won't have a null track in `_upgradeToVideo`.
8400
+ await new Promise(resolve => setTimeout(resolve, 500));
8401
+ }
8385
8402
  reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
8386
8403
  }
8387
8404
  } catch (e) {
@@ -11417,7 +11434,8 @@ class Room$1 extends Emitter {
11417
11434
  }
11418
11435
 
11419
11436
  // Find in all the streams by streamId (used on FF where we can't map by trackId)
11420
- const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) => stream.id === streamId);
11437
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
11438
+ stream && stream.id === streamId);
11421
11439
  return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
11422
11440
  }
11423
11441
 
@@ -7033,6 +7033,8 @@ class WebRTCClient extends Emitter {
7033
7033
  }
7034
7034
  options.sessionDescriptionHandlerOptions = {
7035
7035
  constraints: options.constraints,
7036
+ hold: true,
7037
+ conference: isConference,
7036
7038
  };
7037
7039
 
7038
7040
  // Send re-INVITE
@@ -7075,6 +7077,8 @@ class WebRTCClient extends Emitter {
7075
7077
  }
7076
7078
  options.sessionDescriptionHandlerOptions = {
7077
7079
  constraints: options.constraints,
7080
+ hold: false,
7081
+ conference: isConference,
7078
7082
  };
7079
7083
 
7080
7084
  // Send re-INVITE
@@ -8404,7 +8408,7 @@ class WebRTCPhone extends Emitter {
8404
8408
  return this.client.onDisconnect();
8405
8409
  }
8406
8410
 
8407
- _downgradeToAudio(callSession ) {
8411
+ _downgradeToAudio(callSession , withMessage = true) {
8408
8412
  const sipSession = this.findSipSession(callSession);
8409
8413
  if (!sipSession) {
8410
8414
  return false;
@@ -8431,7 +8435,9 @@ class WebRTCPhone extends Emitter {
8431
8435
  localStream.removeTrack(videoTrack);
8432
8436
  });
8433
8437
 
8434
- this._sendReinviteMessage(callSession, false);
8438
+ if (withMessage) {
8439
+ this._sendReinviteMessage(callSession, false);
8440
+ }
8435
8441
 
8436
8442
  return true;
8437
8443
  }
@@ -8450,9 +8456,9 @@ class WebRTCPhone extends Emitter {
8450
8456
 
8451
8457
  // Check if a video sender already exists
8452
8458
  let videoSender;
8459
+ const videoTransceiver = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
8453
8460
  if (isConference) {
8454
- const trans = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
8455
- videoSender = trans ? trans.sender : null;
8461
+ videoSender = videoTransceiver ? videoTransceiver.sender : null;
8456
8462
  } else {
8457
8463
  videoSender = pc.getSenders().find(sender => sender.track === null);
8458
8464
  }
@@ -8482,6 +8488,11 @@ class WebRTCPhone extends Emitter {
8482
8488
  videoSender.replaceTrack(videoTrack);
8483
8489
  }
8484
8490
 
8491
+ // Put back last direction (was set to `recvonly` when downgrading)
8492
+ if (videoTransceiver && videoTransceiver.currentDirection !== videoTransceiver.direction) {
8493
+ videoTransceiver.direction = videoTransceiver.currentDirection;
8494
+ }
8495
+
8485
8496
  this.client.setLocalMediaStream(this.getSipSessionId(sipSession), newStream);
8486
8497
  this._sendReinviteMessage(callSession, true);
8487
8498
 
@@ -8644,6 +8655,12 @@ class WebRTCPhone extends Emitter {
8644
8655
  // We have to downgrade to audio.
8645
8656
  const screenshareStopped = this.currentScreenShare.sender && this.currentScreenShare.hadVideo;
8646
8657
  const constraints = { audio: false, video: screenshareStopped };
8658
+ if (!conference) {
8659
+ // We have to remove the video sender to be able to re-upgrade to video in `sendReinvite` below
8660
+ this._downgradeToAudio(targetCallSession, false);
8661
+ // Wait for the track to be removed, unless the video sender won't have a null track in `_upgradeToVideo`.
8662
+ await new Promise(resolve => setTimeout(resolve, 500));
8663
+ }
8647
8664
  reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
8648
8665
  }
8649
8666
  } catch (e) {
@@ -11806,7 +11823,8 @@ class Room$1 extends Emitter {
11806
11823
  }
11807
11824
 
11808
11825
  // Find in all the streams by streamId (used on FF where we can't map by trackId)
11809
- const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) => stream.id === streamId);
11826
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
11827
+ stream && stream.id === streamId);
11810
11828
  return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
11811
11829
  }
11812
11830
 
@@ -7033,6 +7033,8 @@ class WebRTCClient extends Emitter {
7033
7033
  }
7034
7034
  options.sessionDescriptionHandlerOptions = {
7035
7035
  constraints: options.constraints,
7036
+ hold: true,
7037
+ conference: isConference,
7036
7038
  };
7037
7039
 
7038
7040
  // Send re-INVITE
@@ -7075,6 +7077,8 @@ class WebRTCClient extends Emitter {
7075
7077
  }
7076
7078
  options.sessionDescriptionHandlerOptions = {
7077
7079
  constraints: options.constraints,
7080
+ hold: false,
7081
+ conference: isConference,
7078
7082
  };
7079
7083
 
7080
7084
  // Send re-INVITE
@@ -8404,7 +8408,7 @@ class WebRTCPhone extends Emitter {
8404
8408
  return this.client.onDisconnect();
8405
8409
  }
8406
8410
 
8407
- _downgradeToAudio(callSession ) {
8411
+ _downgradeToAudio(callSession , withMessage = true) {
8408
8412
  const sipSession = this.findSipSession(callSession);
8409
8413
  if (!sipSession) {
8410
8414
  return false;
@@ -8431,7 +8435,9 @@ class WebRTCPhone extends Emitter {
8431
8435
  localStream.removeTrack(videoTrack);
8432
8436
  });
8433
8437
 
8434
- this._sendReinviteMessage(callSession, false);
8438
+ if (withMessage) {
8439
+ this._sendReinviteMessage(callSession, false);
8440
+ }
8435
8441
 
8436
8442
  return true;
8437
8443
  }
@@ -8450,9 +8456,9 @@ class WebRTCPhone extends Emitter {
8450
8456
 
8451
8457
  // Check if a video sender already exists
8452
8458
  let videoSender;
8459
+ const videoTransceiver = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
8453
8460
  if (isConference) {
8454
- const trans = pc.getTransceivers().find(transceiver => transceiver.mid === '1');
8455
- videoSender = trans ? trans.sender : null;
8461
+ videoSender = videoTransceiver ? videoTransceiver.sender : null;
8456
8462
  } else {
8457
8463
  videoSender = pc.getSenders().find(sender => sender.track === null);
8458
8464
  }
@@ -8482,6 +8488,11 @@ class WebRTCPhone extends Emitter {
8482
8488
  videoSender.replaceTrack(videoTrack);
8483
8489
  }
8484
8490
 
8491
+ // Put back last direction (was set to `recvonly` when downgrading)
8492
+ if (videoTransceiver && videoTransceiver.currentDirection !== videoTransceiver.direction) {
8493
+ videoTransceiver.direction = videoTransceiver.currentDirection;
8494
+ }
8495
+
8485
8496
  this.client.setLocalMediaStream(this.getSipSessionId(sipSession), newStream);
8486
8497
  this._sendReinviteMessage(callSession, true);
8487
8498
 
@@ -8644,6 +8655,12 @@ class WebRTCPhone extends Emitter {
8644
8655
  // We have to downgrade to audio.
8645
8656
  const screenshareStopped = this.currentScreenShare.sender && this.currentScreenShare.hadVideo;
8646
8657
  const constraints = { audio: false, video: screenshareStopped };
8658
+ if (!conference) {
8659
+ // We have to remove the video sender to be able to re-upgrade to video in `sendReinvite` below
8660
+ this._downgradeToAudio(targetCallSession, false);
8661
+ // Wait for the track to be removed, unless the video sender won't have a null track in `_upgradeToVideo`.
8662
+ await new Promise(resolve => setTimeout(resolve, 500));
8663
+ }
8647
8664
  reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
8648
8665
  }
8649
8666
  } catch (e) {
@@ -12672,7 +12689,8 @@ class Room extends Emitter {
12672
12689
  }
12673
12690
 
12674
12691
  // Find in all the streams by streamId (used on FF where we can't map by trackId)
12675
- const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) => stream.id === streamId);
12692
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
12693
+ stream && stream.id === streamId);
12676
12694
  return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
12677
12695
  }
12678
12696