@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
@@ -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) {
@@ -12677,7 +12694,8 @@ class Room extends Emitter {
12677
12694
  }
12678
12695
 
12679
12696
  // Find in all the streams by streamId (used on FF where we can't map by trackId)
12680
- const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) => stream.id === streamId);
12697
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
12698
+ stream && stream.id === streamId);
12681
12699
  return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
12682
12700
  }
12683
12701
 
@@ -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) {
@@ -12951,7 +12968,8 @@ class Room extends Emitter {
12951
12968
  }
12952
12969
 
12953
12970
  // Find in all the streams by streamId (used on FF where we can't map by trackId)
12954
- const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) => stream.id === streamId);
12971
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
12972
+ stream && stream.id === streamId);
12955
12973
  return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
12956
12974
  }
12957
12975
 
@@ -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) {
@@ -12962,7 +12979,8 @@ class Room extends Emitter {
12962
12979
  }
12963
12980
 
12964
12981
  // Find in all the streams by streamId (used on FF where we can't map by trackId)
12965
- const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) => stream.id === streamId);
12982
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
12983
+ stream && stream.id === streamId);
12966
12984
  return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
12967
12985
  }
12968
12986
 
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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
 
@@ -5791,6 +5791,8 @@ class WebRTCClient extends Emitter {
5791
5791
  }
5792
5792
  options.sessionDescriptionHandlerOptions = {
5793
5793
  constraints: options.constraints,
5794
+ hold: true,
5795
+ conference: isConference,
5794
5796
  };
5795
5797
 
5796
5798
  // Send re-INVITE
@@ -5833,6 +5835,8 @@ class WebRTCClient extends Emitter {
5833
5835
  }
5834
5836
  options.sessionDescriptionHandlerOptions = {
5835
5837
  constraints: options.constraints,
5838
+ hold: false,
5839
+ conference: isConference,
5836
5840
  };
5837
5841
 
5838
5842
  // Send re-INVITE
@@ -5797,6 +5797,8 @@ class WebRTCClient extends Emitter {
5797
5797
  }
5798
5798
  options.sessionDescriptionHandlerOptions = {
5799
5799
  constraints: options.constraints,
5800
+ hold: true,
5801
+ conference: isConference,
5800
5802
  };
5801
5803
 
5802
5804
  // Send re-INVITE
@@ -5839,6 +5841,8 @@ class WebRTCClient extends Emitter {
5839
5841
  }
5840
5842
  options.sessionDescriptionHandlerOptions = {
5841
5843
  constraints: options.constraints,
5844
+ hold: false,
5845
+ conference: isConference,
5842
5846
  };
5843
5847
 
5844
5848
  // Send re-INVITE
@@ -6381,6 +6381,8 @@ class WebRTCClient extends Emitter {
6381
6381
  }
6382
6382
  options.sessionDescriptionHandlerOptions = {
6383
6383
  constraints: options.constraints,
6384
+ hold: true,
6385
+ conference: isConference,
6384
6386
  };
6385
6387
 
6386
6388
  // Send re-INVITE
@@ -6423,6 +6425,8 @@ class WebRTCClient extends Emitter {
6423
6425
  }
6424
6426
  options.sessionDescriptionHandlerOptions = {
6425
6427
  constraints: options.constraints,
6428
+ hold: false,
6429
+ conference: isConference,
6426
6430
  };
6427
6431
 
6428
6432
  // Send re-INVITE
@@ -6381,6 +6381,8 @@ class WebRTCClient extends Emitter {
6381
6381
  }
6382
6382
  options.sessionDescriptionHandlerOptions = {
6383
6383
  constraints: options.constraints,
6384
+ hold: true,
6385
+ conference: isConference,
6384
6386
  };
6385
6387
 
6386
6388
  // Send re-INVITE
@@ -6423,6 +6425,8 @@ class WebRTCClient extends Emitter {
6423
6425
  }
6424
6426
  options.sessionDescriptionHandlerOptions = {
6425
6427
  constraints: options.constraints,
6428
+ hold: false,
6429
+ conference: isConference,
6426
6430
  };
6427
6431
 
6428
6432
  // Send re-INVITE
@@ -5797,6 +5797,8 @@ class WebRTCClient extends Emitter {
5797
5797
  }
5798
5798
  options.sessionDescriptionHandlerOptions = {
5799
5799
  constraints: options.constraints,
5800
+ hold: true,
5801
+ conference: isConference,
5800
5802
  };
5801
5803
 
5802
5804
  // Send re-INVITE
@@ -5839,6 +5841,8 @@ class WebRTCClient extends Emitter {
5839
5841
  }
5840
5842
  options.sessionDescriptionHandlerOptions = {
5841
5843
  constraints: options.constraints,
5844
+ hold: false,
5845
+ conference: isConference,
5842
5846
  };
5843
5847
 
5844
5848
  // Send re-INVITE