@wazo/sdk 0.37.2 → 0.37.6

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 (99) hide show
  1. package/dist/wazo-sdk.js +5 -5
  2. package/esm/__tests__/api-client.test.js +84 -22
  3. package/esm/__tests__/web-rtc-client.test.js +156 -55
  4. package/esm/api/call-logd.js +10 -22
  5. package/esm/api/calld.js +3 -0
  6. package/esm/api/confd.js +71 -0
  7. package/esm/api-client.js +84 -22
  8. package/esm/checker/Checker.js +160 -55
  9. package/esm/checker/checks/aor.js +84 -22
  10. package/esm/checker/checks/api.js +84 -22
  11. package/esm/checker/checks/index.js +160 -55
  12. package/esm/checker/checks/wazo-websocket.js +4 -0
  13. package/esm/checker/checks/webrtc-transport.js +156 -55
  14. package/esm/checker/checks/webrtc.js +156 -55
  15. package/esm/domain/AdHocAPIConference.js +84 -22
  16. package/esm/domain/CallLog.js +10 -22
  17. package/esm/domain/Features.js +84 -22
  18. package/esm/domain/Meeting.js +71 -0
  19. package/esm/domain/Phone/CTIPhone.js +84 -22
  20. package/esm/domain/Phone/WebRTCPhone.js +22 -8
  21. package/esm/domain/__tests__/CallLog.test.js +10 -22
  22. package/esm/index.js +726 -371
  23. package/esm/lib/WazoSessionDescriptionHandler.js +17 -9
  24. package/esm/service/CallApi.js +84 -22
  25. package/esm/service/getApiClient.js +84 -22
  26. package/esm/simple/Auth.js +717 -363
  27. package/esm/simple/Configuration.js +717 -363
  28. package/esm/simple/Directory.js +84 -22
  29. package/esm/simple/Phone.js +709 -355
  30. package/esm/simple/Websocket.js +6 -0
  31. package/esm/simple/index.js +719 -365
  32. package/esm/simple/room/LocalParticipant.js +689 -335
  33. package/esm/simple/room/Participant.js +689 -335
  34. package/esm/simple/room/RemoteParticipant.js +689 -335
  35. package/esm/simple/room/Room.js +689 -335
  36. package/esm/simple/room/SipRoom.js +13001 -0
  37. package/esm/simple/room/Stream.js +719 -365
  38. package/esm/simple/room/__tests__/RemoteParticipant.test.js +4130 -3774
  39. package/esm/simple/utils.js +719 -365
  40. package/esm/web-rtc-client.js +156 -55
  41. package/esm/websocket-client.js +5 -1
  42. package/lib/__tests__/api-client.test.js +84 -22
  43. package/lib/__tests__/web-rtc-client.test.js +156 -55
  44. package/lib/api/call-logd.js +10 -22
  45. package/lib/api/calld.js +3 -0
  46. package/lib/api/confd.js +71 -0
  47. package/lib/api-client.js +84 -22
  48. package/lib/checker/Checker.js +160 -55
  49. package/lib/checker/checks/aor.js +84 -22
  50. package/lib/checker/checks/api.js +84 -22
  51. package/lib/checker/checks/index.js +160 -55
  52. package/lib/checker/checks/wazo-websocket.js +4 -0
  53. package/lib/checker/checks/webrtc-transport.js +156 -55
  54. package/lib/checker/checks/webrtc.js +156 -55
  55. package/lib/domain/AdHocAPIConference.js +84 -22
  56. package/lib/domain/CallLog.js +10 -22
  57. package/lib/domain/Features.js +84 -22
  58. package/lib/domain/Meeting.js +73 -0
  59. package/lib/domain/Phone/CTIPhone.js +84 -22
  60. package/lib/domain/Phone/WebRTCPhone.js +22 -8
  61. package/lib/domain/__tests__/CallLog.test.js +10 -22
  62. package/lib/index.js +726 -371
  63. package/lib/lib/WazoSessionDescriptionHandler.js +17 -9
  64. package/lib/service/CallApi.js +84 -22
  65. package/lib/service/getApiClient.js +84 -22
  66. package/lib/simple/Auth.js +717 -363
  67. package/lib/simple/Configuration.js +717 -363
  68. package/lib/simple/Directory.js +84 -22
  69. package/lib/simple/Phone.js +709 -355
  70. package/lib/simple/Websocket.js +6 -0
  71. package/lib/simple/index.js +719 -365
  72. package/lib/simple/room/LocalParticipant.js +689 -335
  73. package/lib/simple/room/Participant.js +689 -335
  74. package/lib/simple/room/RemoteParticipant.js +689 -335
  75. package/lib/simple/room/Room.js +689 -335
  76. package/lib/simple/room/SipRoom.js +13011 -0
  77. package/lib/simple/room/Stream.js +719 -365
  78. package/lib/simple/room/__tests__/RemoteParticipant.test.js +4131 -3775
  79. package/lib/simple/utils.js +719 -365
  80. package/lib/web-rtc-client.js +156 -55
  81. package/lib/websocket-client.js +6 -0
  82. package/package.json +1 -1
  83. package/src/api/calld.js +3 -0
  84. package/src/api/confd.js +13 -0
  85. package/src/domain/CallLog.js +10 -22
  86. package/src/domain/Meeting.js +59 -0
  87. package/src/domain/Phone/WebRTCPhone.js +22 -8
  88. package/src/index.js +2 -0
  89. package/src/lib/WazoSessionDescriptionHandler.js +17 -9
  90. package/src/simple/Phone.js +13 -4
  91. package/src/simple/index.js +4 -0
  92. package/src/simple/room/Participant.js +7 -0
  93. package/src/simple/room/Room.js +158 -79
  94. package/src/simple/room/SipRoom.js +147 -0
  95. package/src/simple/room/Stream.js +1 -3
  96. package/src/simple/room/__tests__/RemoteParticipant.test.js +3 -2
  97. package/src/types/WebSocketMessage.js +21 -0
  98. package/src/web-rtc-client.js +55 -24
  99. package/src/websocket-client.js +4 -0
@@ -1850,7 +1850,7 @@ var IssueReporter$1 = new IssueReporter();
1850
1850
 
1851
1851
  const methods = ['head', 'get', 'post', 'put', 'delete'];
1852
1852
 
1853
- const logger$b = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
1853
+ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
1854
1854
 
1855
1855
  // Use a function here to be able to mock it in tests
1856
1856
  const realFetch = () => {
@@ -1989,7 +1989,7 @@ class ApiRequester {
1989
1989
  };
1990
1990
 
1991
1991
  if (this.refreshTokenPromise) {
1992
- logger$b.info('A token is already refreshing, waiting ...', { url });
1992
+ logger$c.info('A token is already refreshing, waiting ...', { url });
1993
1993
  await this.refreshTokenPromise;
1994
1994
  }
1995
1995
 
@@ -2009,7 +2009,7 @@ class ApiRequester {
2009
2009
  return promise.then(async (err ) => {
2010
2010
  // Check if the token is still valid
2011
2011
  if (firstCall && this._checkTokenExpired(response, err)) {
2012
- logger$b.warn('token expired', { error: err.reason });
2012
+ logger$c.warn('token expired', { error: err.reason });
2013
2013
  // Replay the call after refreshing the token
2014
2014
  return this._replayWithNewToken(err, path, method, body, headers, parse);
2015
2015
  }
@@ -2019,7 +2019,7 @@ class ApiRequester {
2019
2019
  : exceptionClass.fromResponse(err, response.status);
2020
2020
 
2021
2021
  if (this.shouldLogErrors) {
2022
- logger$b.error('API error', error);
2022
+ logger$c.error('API error', error);
2023
2023
  }
2024
2024
 
2025
2025
  throw error;
@@ -2029,7 +2029,7 @@ class ApiRequester {
2029
2029
  return newParse(response, isJson);
2030
2030
  }).catch(error => {
2031
2031
  if (this.shouldLogErrors) {
2032
- logger$b.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
2032
+ logger$c.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
2033
2033
  }
2034
2034
 
2035
2035
  throw error;
@@ -2057,13 +2057,13 @@ class ApiRequester {
2057
2057
  ) {
2058
2058
  const isTokenNotFound = this._isTokenNotFound(err);
2059
2059
  let newPath = path;
2060
- logger$b.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
2060
+ logger$c.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
2061
2061
 
2062
2062
  this.refreshTokenPromise = this.refreshTokenPromise || this.refreshTokenCallback();
2063
2063
 
2064
2064
  return this.refreshTokenPromise.then(() => {
2065
2065
  this.refreshTokenPromise = null;
2066
- logger$b.info('token refreshed', { isTokenNotFound });
2066
+ logger$c.info('token refreshed', { isTokenNotFound });
2067
2067
  if (isTokenNotFound) {
2068
2068
  const pathParts = path.split('/');
2069
2069
  pathParts.pop();
@@ -2524,6 +2524,65 @@ class ExternalApp {
2524
2524
  }
2525
2525
  }
2526
2526
 
2527
+ //
2528
+
2529
+
2530
+
2531
+
2532
+
2533
+
2534
+
2535
+
2536
+
2537
+
2538
+
2539
+ class Meeting {
2540
+
2541
+
2542
+
2543
+
2544
+
2545
+
2546
+
2547
+
2548
+
2549
+
2550
+ static parse(plain ) {
2551
+ return new Meeting({
2552
+ guestSipAuthorization: plain.guest_sip_authorization,
2553
+ hostname: plain.hostname,
2554
+ name: plain.name,
2555
+ ownerUuids: plain.owner_uuids,
2556
+ port: plain.port,
2557
+ uuid: plain.uuid,
2558
+ number: plain.number,
2559
+ });
2560
+ }
2561
+
2562
+ static newFrom(meeting ) {
2563
+ return newFrom(meeting, Meeting);
2564
+ }
2565
+
2566
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
2567
+ this.guestSipAuthorization = guestSipAuthorization;
2568
+ this.hostname = hostname;
2569
+ this.name = name;
2570
+ this.ownerUuids = ownerUuids;
2571
+ this.port = port;
2572
+ this.uuid = uuid;
2573
+ this.number = number;
2574
+
2575
+ // Useful to compare instead of instanceof with minified code
2576
+ this.type = 'Meeting';
2577
+ }
2578
+
2579
+ getGuestSipCredentials() {
2580
+ // eslint-disable-next-line no-undef
2581
+ const [username, secret] = atob(this.guestSipAuthorization).split(':');
2582
+ return { username, secret };
2583
+ }
2584
+ }
2585
+
2527
2586
  /* */
2528
2587
 
2529
2588
  var confdMethods = (client , baseUrl ) => ({
@@ -2588,6 +2647,18 @@ var confdMethods = (client , baseUrl ) => ({
2588
2647
  return null;
2589
2648
  }
2590
2649
  },
2650
+
2651
+ createMyMeeting: (name ) =>
2652
+ client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
2653
+
2654
+ deleteMyMeeting: (meetingUuid ) =>
2655
+ client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
2656
+
2657
+ getMeeting: (meetingUuid ) =>
2658
+ client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
2659
+
2660
+ guestGetMeeting: (meetingUuid ) =>
2661
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
2591
2662
  });
2592
2663
 
2593
2664
  //
@@ -3530,7 +3601,11 @@ class CallLog {
3530
3601
  answered: plain.answered,
3531
3602
  callDirection: plain.call_direction,
3532
3603
  destination: {
3533
- extension: plain.requested_extension || plain.destination_extension,
3604
+ // @TEMP: Temporarily assuming empty numbers are meetings
3605
+ // which is admittedly a very dangerous assumption. Did i mention it was temporary?
3606
+ extension: plain.requested_extension
3607
+ || plain.destination_extension
3608
+ || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3534
3609
  name: plain.requested_name || plain.destination_name || '',
3535
3610
  },
3536
3611
  source: {
@@ -3546,27 +3621,11 @@ class CallLog {
3546
3621
  }
3547
3622
 
3548
3623
  static parseNew(plain , session ) {
3549
- return new CallLog({
3550
- answer: plain.answer ? moment__default['default'](plain.answer).toDate() : null,
3551
- answered: plain.answered,
3552
- callDirection: plain.call_direction,
3553
- destination: {
3554
- extension: plain.requested_extension || plain.destination_extension,
3555
- name: plain.requested_name || plain.destination_name || '',
3556
- },
3557
- source: {
3558
- extension: plain.source_extension,
3559
- name: plain.source_name,
3560
- },
3561
- id: plain.id,
3562
- duration: (plain.duration || 0) * 1000, // duration is in seconds
3563
- start: moment__default['default'](plain.start).toDate(),
3564
- end: plain.end ? moment__default['default'](plain.end).toDate() : null,
3565
- recordings: Recording.parseMany(plain.recordings),
3566
- // @TODO: FIXME add verification declined vs missed call
3567
- newMissedCall: session
3568
- && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
3569
- });
3624
+ const callLog = CallLog.parse(plain);
3625
+ // @TODO: FIXME add verification declined vs missed call
3626
+ callLog.newMissedCall = session
3627
+ && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
3628
+ return callLog;
3570
3629
  }
3571
3630
 
3572
3631
  static newFrom(profile ) {
@@ -3831,7 +3890,7 @@ const TRANSFER_FLOW_BLIND = 'blind';
3831
3890
 
3832
3891
  // const MINIMUM_WAZO_ENGINE_VERSION_FOR_CTI_HOLD = '20.11';
3833
3892
 
3834
- const logger$a = IssueReporter$1 ? IssueReporter$1.loggerFor('cti-phone') : console;
3893
+ const logger$b = IssueReporter$1 ? IssueReporter$1.loggerFor('cti-phone') : console;
3835
3894
 
3836
3895
  class CTIPhone extends Emitter {
3837
3896
 
@@ -3844,7 +3903,7 @@ class CTIPhone extends Emitter {
3844
3903
 
3845
3904
  constructor(session , isMobile = false, callbackAllLines = false) {
3846
3905
  super();
3847
- logger$a.info('CTI Phone created');
3906
+ logger$b.info('CTI Phone created');
3848
3907
  this.session = session;
3849
3908
  this.isMobile = isMobile;
3850
3909
  this.callbackAllLines = callbackAllLines;
@@ -3905,7 +3964,7 @@ class CTIPhone extends Emitter {
3905
3964
  }
3906
3965
 
3907
3966
  async makeCall(number , line ) {
3908
- logger$a.info('make CTI call', { number });
3967
+ logger$b.info('make CTI call', { number });
3909
3968
 
3910
3969
  if (!number) {
3911
3970
  return null;
@@ -3928,7 +3987,7 @@ class CTIPhone extends Emitter {
3928
3987
  if (!callSession) {
3929
3988
  return Promise.resolve(null);
3930
3989
  }
3931
- logger$a.info('accept CTI call', { callId: callSession.getId(), number: callSession.number });
3990
+ logger$b.info('accept CTI call', { callId: callSession.getId(), number: callSession.number });
3932
3991
 
3933
3992
  if (!this.currentCall) {
3934
3993
  this.currentCall = callSession.call;
@@ -3941,7 +4000,7 @@ class CTIPhone extends Emitter {
3941
4000
  if (!callSession) {
3942
4001
  return;
3943
4002
  }
3944
- logger$a.info('end current CTI call', { callId: callSession.getId(), number: callSession.number });
4003
+ logger$b.info('end current CTI call', { callId: callSession.getId(), number: callSession.number });
3945
4004
 
3946
4005
  this.currentCall = undefined;
3947
4006
  this.eventEmitter.emit('onCallEnded', callSession);
@@ -3951,7 +4010,7 @@ class CTIPhone extends Emitter {
3951
4010
  if (!callSession) {
3952
4011
  return Promise.resolve(false);
3953
4012
  }
3954
- logger$a.info('hangup CTI call', { callId: callSession.getId(), number: callSession.number });
4013
+ logger$b.info('hangup CTI call', { callId: callSession.getId(), number: callSession.number });
3955
4014
 
3956
4015
  try {
3957
4016
  await CallApi.cancelCall(callSession);
@@ -3962,7 +4021,7 @@ class CTIPhone extends Emitter {
3962
4021
  this.eventEmitter.emit('onCallEnded', callSession);
3963
4022
  return true;
3964
4023
  } catch (e) {
3965
- logger$a.error('hangup CTI call, error', e);
4024
+ logger$b.error('hangup CTI call, error', e);
3966
4025
 
3967
4026
  this.eventEmitter.emit('onCallFailed', callSession);
3968
4027
  return false;
@@ -3975,7 +4034,7 @@ class CTIPhone extends Emitter {
3975
4034
  if (!callSession) {
3976
4035
  return;
3977
4036
  }
3978
- logger$a.info('reject CTI call', { callId: callSession.getId(), number: callSession.number });
4037
+ logger$b.info('reject CTI call', { callId: callSession.getId(), number: callSession.number });
3979
4038
 
3980
4039
  await CallApi.cancelCall(callSession);
3981
4040
  this.eventEmitter.emit('onCallEnded', callSession);
@@ -3985,7 +4044,7 @@ class CTIPhone extends Emitter {
3985
4044
  if (!callSession) {
3986
4045
  return;
3987
4046
  }
3988
- logger$a.info('transfer CTI call', { callId: callSession.getId(), number: callSession.number, to: number });
4047
+ logger$b.info('transfer CTI call', { callId: callSession.getId(), number: callSession.number, to: number });
3989
4048
 
3990
4049
  await CallApi.transferCall(callSession.callId, number, TRANSFER_FLOW_BLIND);
3991
4050
  }
@@ -3996,19 +4055,19 @@ class CTIPhone extends Emitter {
3996
4055
  if (!callSession) {
3997
4056
  return;
3998
4057
  }
3999
- logger$a.info('indirect CTI transfer', { callId: callSession.getId(), number: callSession.number, to: number });
4058
+ logger$b.info('indirect CTI transfer', { callId: callSession.getId(), number: callSession.number, to: number });
4000
4059
 
4001
4060
  return CallApi.transferCall(callSession.callId, number, TRANSFER_FLOW_ATTENDED);
4002
4061
  }
4003
4062
 
4004
4063
  async cancelCTIIndirectTransfer(transferId ) {
4005
- logger$a.info('cancel CTI transfer', { transferId });
4064
+ logger$b.info('cancel CTI transfer', { transferId });
4006
4065
 
4007
4066
  return CallApi.cancelCallTransfer(transferId);
4008
4067
  }
4009
4068
 
4010
4069
  async confirmCTIIndirectTransfer(transferId ) {
4011
- logger$a.info('confirm CTI transfer', { transferId });
4070
+ logger$b.info('confirm CTI transfer', { transferId });
4012
4071
 
4013
4072
  return CallApi.confirmCallTransfer(transferId);
4014
4073
  }
@@ -4017,19 +4076,19 @@ class CTIPhone extends Emitter {
4017
4076
  if (!callSession) {
4018
4077
  return;
4019
4078
  }
4020
- logger$a.info('send CTI key', { callId: callSession.getId(), number: callSession.number, digits });
4079
+ logger$b.info('send CTI key', { callId: callSession.getId(), number: callSession.number, digits });
4021
4080
 
4022
4081
  return CallApi.sendDTMF(callSession.callId, digits);
4023
4082
  }
4024
4083
 
4025
4084
  onConnectionMade() {
4026
- logger$a.info('on CTI connection made');
4085
+ logger$b.info('on CTI connection made');
4027
4086
 
4028
4087
  this.eventEmitter.emit('onCallAccepted');
4029
4088
  }
4030
4089
 
4031
4090
  async close() {
4032
- logger$a.info('CTI close');
4091
+ logger$b.info('CTI close');
4033
4092
 
4034
4093
  return Promise.resolve();
4035
4094
  }
@@ -4038,7 +4097,7 @@ class CTIPhone extends Emitter {
4038
4097
  if (!callSession) {
4039
4098
  return;
4040
4099
  }
4041
- logger$a.info('CTI hold', { callId: callSession.getId(), number: callSession.number });
4100
+ logger$b.info('CTI hold', { callId: callSession.getId(), number: callSession.number });
4042
4101
 
4043
4102
  return CallApi.hold(callSession.callId);
4044
4103
  }
@@ -4047,7 +4106,7 @@ class CTIPhone extends Emitter {
4047
4106
  if (!callSession) {
4048
4107
  return;
4049
4108
  }
4050
- logger$a.info('CTI resume', { callId: callSession.getId(), number: callSession.number });
4109
+ logger$b.info('CTI resume', { callId: callSession.getId(), number: callSession.number });
4051
4110
 
4052
4111
  return CallApi.resume(callSession.callId);
4053
4112
  }
@@ -4056,7 +4115,7 @@ class CTIPhone extends Emitter {
4056
4115
  if (!callSession) {
4057
4116
  return;
4058
4117
  }
4059
- logger$a.info('CTI mute', { callId: callSession.getId(), number: callSession.number });
4118
+ logger$b.info('CTI mute', { callId: callSession.getId(), number: callSession.number });
4060
4119
 
4061
4120
  return CallApi.mute(callSession.callId);
4062
4121
  }
@@ -4065,7 +4124,7 @@ class CTIPhone extends Emitter {
4065
4124
  if (!callSession) {
4066
4125
  return;
4067
4126
  }
4068
- logger$a.info('CTI unmute', { callId: callSession.getId(), number: callSession.number });
4127
+ logger$b.info('CTI unmute', { callId: callSession.getId(), number: callSession.number });
4069
4128
 
4070
4129
  return CallApi.unmute(callSession.callId);
4071
4130
  }
@@ -4711,6 +4770,9 @@ var calldMethods = (client , baseUrl ) => ({
4711
4770
  getConferenceParticipantsAsUser: async (conferenceId ) =>
4712
4771
  client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
4713
4772
 
4773
+ getMeetingParticipantsAsUser: async (meetingUuid ) =>
4774
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
4775
+
4714
4776
  listTrunks: () => client.get(`${baseUrl}/trunks`),
4715
4777
 
4716
4778
  mute: (callId ) =>
@@ -5064,7 +5126,7 @@ const AGENTD_VERSION = '1.0';
5064
5126
  const WEBHOOKD_VERSION = '1.0';
5065
5127
  const AMID_VERSION = '1.0';
5066
5128
 
5067
- const logger$9 = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
5129
+ const logger$a = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
5068
5130
 
5069
5131
  class ApiClient {
5070
5132
 
@@ -5116,12 +5178,12 @@ class ApiClient {
5116
5178
  }
5117
5179
 
5118
5180
  async forceRefreshToken() {
5119
- logger$9.info('forcing refresh token, calling callback');
5181
+ logger$a.info('forcing refresh token, calling callback');
5120
5182
  return this.refreshTokenCallback();
5121
5183
  }
5122
5184
 
5123
5185
  async refreshTokenCallback() {
5124
- logger$9.info('refresh token callback called', {
5186
+ logger$a.info('refresh token callback called', {
5125
5187
  refreshToken: this.refreshToken,
5126
5188
  refreshBackend: this.refreshBackend,
5127
5189
  refreshExpiration: this.refreshExpiration,
@@ -5139,7 +5201,7 @@ class ApiClient {
5139
5201
  this.isMobile,
5140
5202
  );
5141
5203
 
5142
- logger$9.info('token refreshed', { token: session.token });
5204
+ logger$a.info('token refreshed', { token: session.token });
5143
5205
 
5144
5206
  if (this.onRefreshToken) {
5145
5207
  this.onRefreshToken(session.token, session);
@@ -5612,7 +5674,9 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5612
5674
  .then(() => {
5613
5675
  if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
5614
5676
  // Add a video an empty bundle to be able to replaceTrack when joining a conference without video
5615
- this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5677
+ if (this.peerConnection.addTransceiver) {
5678
+ this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5679
+ }
5616
5680
  }
5617
5681
  })
5618
5682
  .then(() => this.createLocalOfferOrAnswer(options))
@@ -5639,12 +5703,6 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5639
5703
  };
5640
5704
  })
5641
5705
  .then((sessionDescription) => this.applyModifiers(sessionDescription, modifiers))
5642
- .then((sessionDescription) => {
5643
- // Set new constraints to avoid the constraints check issue in `sdh.getLocalMediaStream` later.
5644
- this.localMediaStreamConstraints = options.constraints;
5645
-
5646
- return sessionDescription;
5647
- })
5648
5706
  .then((sessionDescription) => ({ body: sessionDescription.sdp, contentType: 'application/sdp' }))
5649
5707
  .catch((error) => {
5650
5708
  wazoLogger.error('error when creating media', error);
@@ -5839,6 +5897,9 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5839
5897
 
5840
5898
  // set the transceiver direction to the answer direction
5841
5899
  this._peerConnection.getTransceivers().forEach((transceiver) => {
5900
+ if (transceiver.stopped) {
5901
+ return;
5902
+ }
5842
5903
  if (transceiver.direction /* guarding, but should always be true */) {
5843
5904
  const { receiver } = transceiver;
5844
5905
  if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
@@ -5883,10 +5944,15 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5883
5944
  if (kind !== 'audio' && kind !== 'video') {
5884
5945
  throw new Error(`Unknown new track kind ${kind}.`);
5885
5946
  }
5886
- const sender = pc.getSenders().find((otherSender) => otherSender.track && otherSender.track.kind === kind);
5947
+ const sender = pc.getSenders && pc.getSenders().find((otherSender) =>
5948
+ otherSender.track && otherSender.track.kind === kind);
5887
5949
 
5888
5950
  // Do not reuse sender video tracks in SFU
5889
5951
  if (sender && (!sfu || newTrack.kind === 'audio')) {
5952
+ if (sender.track) {
5953
+ // eslint-disable-next-line no-param-reassign
5954
+ newTrack.enabled = sender.track.enabled;
5955
+ }
5890
5956
  trackUpdates.push(
5891
5957
  new Promise((resolve) => {
5892
5958
  this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
@@ -5920,7 +5986,11 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5920
5986
  // Review: could make streamless tracks a configurable option?
5921
5987
  // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack#Usage_notes
5922
5988
  try {
5923
- pc.addTrack(newTrack, localStream);
5989
+ if (pc.addTrack) {
5990
+ pc.addTrack(newTrack, localStream);
5991
+ } else {
5992
+ pc.addStream(localStream);
5993
+ }
5924
5994
  } catch (error) {
5925
5995
  this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to add sender ${kind} track`);
5926
5996
  throw error;
@@ -6056,7 +6126,7 @@ const DEFAULT_ICE_TIMEOUT = 3000;
6056
6126
  const SEND_STATS_DELAY = 5000;
6057
6127
 
6058
6128
  const states = ['STATUS_NULL', 'STATUS_NEW', 'STATUS_CONNECTING', 'STATUS_CONNECTED', 'STATUS_COMPLETED'];
6059
- const logger$8 = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-client') : console;
6129
+ const logger$9 = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-client') : console;
6060
6130
  const statsLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-stats') : console;
6061
6131
 
6062
6132
  // events
@@ -6102,6 +6172,7 @@ const MAX_REGISTER_TRIES = 10;
6102
6172
 
6103
6173
 
6104
6174
 
6175
+
6105
6176
 
6106
6177
 
6107
6178
 
@@ -6128,6 +6199,7 @@ class WebRTCClient extends Emitter {
6128
6199
 
6129
6200
 
6130
6201
 
6202
+
6131
6203
 
6132
6204
  // sugar
6133
6205
 
@@ -6166,6 +6238,8 @@ class WebRTCClient extends Emitter {
6166
6238
  super();
6167
6239
  this.uaConfigOverrides = uaConfigOverrides;
6168
6240
  this.config = config;
6241
+ this.skipRegister = config.skipRegister;
6242
+
6169
6243
  this._buildConfig(config, session).then((newConfig ) => {
6170
6244
  this.config = newConfig;
6171
6245
  this.userAgent = this.createUserAgent(uaConfigOverrides);
@@ -6221,13 +6295,13 @@ class WebRTCClient extends Emitter {
6221
6295
 
6222
6296
  createUserAgent(configOverrides ) {
6223
6297
  const webRTCConfiguration = this._createWebRTCConfiguration(configOverrides);
6224
- logger$8.info('sdk webrtc, creating UA', { webRTCConfiguration });
6298
+ logger$9.info('sdk webrtc, creating UA', { webRTCConfiguration });
6225
6299
 
6226
6300
  webRTCConfiguration.delegate = {
6227
6301
  onConnect: this.onConnect.bind(this),
6228
6302
  onDisconnect: this.onDisconnect.bind(this),
6229
6303
  onInvite: (invitation ) => {
6230
- logger$8.info('sdk webrtc on invite', {
6304
+ logger$9.info('sdk webrtc on invite', {
6231
6305
  method: 'delegate.onInvite',
6232
6306
  id: invitation.id,
6233
6307
  remoteURI: invitation.remoteURI,
@@ -6270,7 +6344,7 @@ class WebRTCClient extends Emitter {
6270
6344
  }
6271
6345
 
6272
6346
  onConnect() {
6273
- logger$8.info('sdk webrtc connected', { method: 'delegate.onConnect' });
6347
+ logger$9.info('sdk webrtc connected', { method: 'delegate.onConnect' });
6274
6348
  this.eventEmitter.emit(CONNECTED);
6275
6349
  if (!this.isRegistered() && this.registerer && this.registerer.waiting) {
6276
6350
  this.registerer.waitingToggle(false);
@@ -6279,7 +6353,7 @@ class WebRTCClient extends Emitter {
6279
6353
  }
6280
6354
 
6281
6355
  async onDisconnect(error ) {
6282
- logger$8.info('sdk webrtc disconnected', { method: 'delegate.onConnect', error });
6356
+ logger$9.info('sdk webrtc disconnected', { method: 'delegate.onConnect', error });
6283
6357
  this.connectionPromise = null;
6284
6358
  // The UA will attempt to reconnect automatically when an error occurred
6285
6359
  this.eventEmitter.emit(DISCONNECTED, error);
@@ -6293,40 +6367,48 @@ class WebRTCClient extends Emitter {
6293
6367
  }
6294
6368
 
6295
6369
  register(tries = 0) {
6296
- logger$8.info('sdk webrtc registering...', {
6370
+ const logInfo = {
6297
6371
  userAgent: !!this.userAgent,
6298
6372
  registered: this.isRegistered(),
6299
6373
  connectionPromise: !!this.connectionPromise,
6300
6374
  registerer: !!this.registerer,
6301
6375
  waiting: this.registerer && this.registerer.waiting,
6302
6376
  tries,
6303
- });
6377
+ skipRegister: this.skipRegister,
6378
+ };
6379
+
6380
+ if (this.skipRegister) {
6381
+ logger$9.info('sdk webrtc skip register...', logInfo);
6382
+ return Promise.resolve();
6383
+ }
6384
+
6385
+ logger$9.info('sdk webrtc registering...', logInfo);
6304
6386
 
6305
6387
  if (!this.userAgent) {
6306
- logger$8.info('sdk webrtc recreating User Agent');
6388
+ logger$9.info('sdk webrtc recreating User Agent');
6307
6389
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
6308
6390
  }
6309
6391
  if (!this.userAgent || this.isRegistered()) {
6310
- logger$8.info('sdk webrtc registering aborted, already registered or no UA can be created');
6392
+ logger$9.info('sdk webrtc registering aborted, already registered or no UA can be created');
6311
6393
  return Promise.resolve();
6312
6394
  }
6313
6395
 
6314
6396
  if (this.connectionPromise || (this.registerer && this.registerer.waiting)) {
6315
- logger$8.info('sdk webrtc registering aborted due to a registration in progress.');
6397
+ logger$9.info('sdk webrtc registering aborted due to a registration in progress.');
6316
6398
  return Promise.resolve();
6317
6399
  }
6318
6400
 
6319
6401
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6320
6402
 
6321
6403
  const onRegisterFailed = () => {
6322
- logger$8.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6404
+ logger$9.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6323
6405
  this.connectionPromise = null;
6324
6406
  if (this.registerer && this.registerer.waiting) {
6325
6407
  this.registerer.waitingToggle(false);
6326
6408
  }
6327
6409
 
6328
6410
  if (tries <= MAX_REGISTER_TRIES) {
6329
- logger$8.info('sdk webrtc registering, retrying...', { tries });
6411
+ logger$9.info('sdk webrtc registering, retrying...', { tries });
6330
6412
  setTimeout(() => this.register(tries + 1), 300);
6331
6413
  }
6332
6414
  };
@@ -6335,18 +6417,18 @@ class WebRTCClient extends Emitter {
6335
6417
  // Avoid race condition with the close method called just before register and setting userAgent to null
6336
6418
  // during the resolution of the primise.
6337
6419
  if (!this.userAgent) {
6338
- logger$8.info('sdk webrtc recreating User Agent after connection');
6420
+ logger$9.info('sdk webrtc recreating User Agent after connection');
6339
6421
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
6340
6422
  }
6341
6423
 
6342
- logger$8.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent });
6424
+ logger$9.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent });
6343
6425
  this.registerer = new registerer.Registerer(this.userAgent, registerOptions);
6344
6426
  this.connectionPromise = null;
6345
6427
  this._monkeyPatchRegisterer(this.registerer);
6346
6428
 
6347
6429
  // Bind registerer events
6348
6430
  this.registerer.stateChange.addListener(newState => {
6349
- logger$8.info('sdk webrtc registering, state changed', { newState });
6431
+ logger$9.info('sdk webrtc registering, state changed', { newState });
6350
6432
 
6351
6433
  if (newState === registererState.RegistererState.Registered && this.registerer
6352
6434
  && this.registerer.state === registererState.RegistererState.Registered) {
@@ -6359,7 +6441,7 @@ class WebRTCClient extends Emitter {
6359
6441
  const options = {
6360
6442
  requestDelegate: {
6361
6443
  onReject: response => {
6362
- logger$8.error('sdk webrtc registering, rejected', { response });
6444
+ logger$9.error('sdk webrtc registering, rejected', { response });
6363
6445
 
6364
6446
  onRegisterFailed();
6365
6447
  },
@@ -6367,13 +6449,13 @@ class WebRTCClient extends Emitter {
6367
6449
  };
6368
6450
 
6369
6451
  return this.registerer.register(options).catch((e) => {
6370
- logger$8.error('sdk webrtc registering, error', e);
6452
+ logger$9.error('sdk webrtc registering, error', e);
6371
6453
 
6372
6454
  this.eventEmitter.emit(REGISTRATION_FAILED);
6373
6455
  return e;
6374
6456
  });
6375
6457
  }).catch(error => {
6376
- logger$8.error('sdk webrtc registering, transport error', error);
6458
+ logger$9.error('sdk webrtc registering, transport error', error);
6377
6459
  onRegisterFailed();
6378
6460
  });
6379
6461
  }
@@ -6402,21 +6484,21 @@ class WebRTCClient extends Emitter {
6402
6484
  }
6403
6485
 
6404
6486
  unregister() {
6405
- logger$8.info('sdk webrtc unregistering..', { userAgent: !!this.userAgent, registerer: !!this.registerer });
6487
+ logger$9.info('sdk webrtc unregistering..', { userAgent: !!this.userAgent, registerer: !!this.registerer });
6406
6488
  if (!this.registerer) {
6407
6489
  return Promise.resolve();
6408
6490
  }
6409
6491
 
6410
6492
  try {
6411
6493
  return this.registerer.unregister().then(() => {
6412
- logger$8.info('sdk webrtc unregistered');
6494
+ logger$9.info('sdk webrtc unregistered');
6413
6495
  this._cleanupRegister();
6414
6496
  }).catch(e => {
6415
- logger$8.error('sdk webrtc unregistering, promise error', e);
6497
+ logger$9.error('sdk webrtc unregistering, promise error', e);
6416
6498
  this._cleanupRegister();
6417
6499
  });
6418
6500
  } catch (e) {
6419
- logger$8.error('sdk webrtc unregistering, error', e);
6501
+ logger$9.error('sdk webrtc unregistering, error', e);
6420
6502
  // Avoid issue with `undefined is not an object (evaluating 'new.target.prototype')` when triggering a new
6421
6503
  // error when the registerer is in a bad state
6422
6504
  this._cleanupRegister();
@@ -6424,7 +6506,7 @@ class WebRTCClient extends Emitter {
6424
6506
  }
6425
6507
 
6426
6508
  stop() {
6427
- logger$8.info('sdk webrtc stop', { userAgent: !!this.userAgent });
6509
+ logger$9.info('sdk webrtc stop', { userAgent: !!this.userAgent });
6428
6510
  if (!this.userAgent) {
6429
6511
  return Promise.resolve();
6430
6512
  }
@@ -6432,12 +6514,12 @@ class WebRTCClient extends Emitter {
6432
6514
  return this.userAgent.stop().then(() => {
6433
6515
  return this._cleanupRegister();
6434
6516
  }).catch(e => {
6435
- logger$8.warn('sdk webrtc stop, error', { message: e.message, stack: e.stack });
6517
+ logger$9.warn('sdk webrtc stop, error', { message: e.message, stack: e.stack });
6436
6518
  });
6437
6519
  }
6438
6520
 
6439
6521
  call(number , enableVideo , audioOnly = false, conference = false) {
6440
- logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6522
+ logger$9.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6441
6523
  const inviterOptions = {
6442
6524
  sessionDescriptionHandlerOptionsReInvite: {
6443
6525
  conference,
@@ -6466,7 +6548,7 @@ class WebRTCClient extends Emitter {
6466
6548
  this._onAccepted(session, response.session, true);
6467
6549
  },
6468
6550
  onReject: (response ) => {
6469
- logger$8.info('on call rejected', { id: session.id, fromTag: session.fromTag });
6551
+ logger$9.info('on call rejected', { id: session.id, fromTag: session.fromTag });
6470
6552
  this._stopSendingStats(session);
6471
6553
 
6472
6554
  this.eventEmitter.emit(REJECTED, session, response);
@@ -6488,11 +6570,11 @@ class WebRTCClient extends Emitter {
6488
6570
  }
6489
6571
 
6490
6572
  answer(session , enableVideo ) {
6491
- logger$8.info('sdk webrtc answer call', { id: session.id, enableVideo });
6573
+ logger$9.info('sdk webrtc answer call', { id: session.id, enableVideo });
6492
6574
 
6493
6575
  if (!session || !session.accept) {
6494
6576
  const error = 'No session to answer, or not an invitation';
6495
- logger$8.warn(error);
6577
+ logger$9.warn(error);
6496
6578
  return Promise.reject(new Error(error));
6497
6579
  }
6498
6580
  const options = {
@@ -6502,15 +6584,15 @@ class WebRTCClient extends Emitter {
6502
6584
  return session.accept(options).then(() => {
6503
6585
  if (session.isCanceled) {
6504
6586
  const message = 'accepted a canceled session (or was canceled during the accept phase).';
6505
- logger$8.error(message, { id: session.id });
6587
+ logger$9.error(message, { id: session.id });
6506
6588
  this.onCallEnded(session);
6507
6589
 
6508
6590
  throw new CanceledCallError(message);
6509
6591
  }
6510
- logger$8.info('sdk webrtc answer, accepted.');
6592
+ logger$9.info('sdk webrtc answer, accepted.');
6511
6593
  this._onAccepted(session);
6512
6594
  }).catch(e => {
6513
- logger$8.error(`answer call error for ${session ? session.id : 'n/a'}`, e);
6595
+ logger$9.error(`answer call error for ${session ? session.id : 'n/a'}`, e);
6514
6596
 
6515
6597
  throw e;
6516
6598
  });
@@ -6518,7 +6600,7 @@ class WebRTCClient extends Emitter {
6518
6600
 
6519
6601
  hangup(session ) {
6520
6602
  const { state, id } = session;
6521
- logger$8.info('sdk webrtc hangup call', { id, state });
6603
+ logger$9.info('sdk webrtc hangup call', { id, state });
6522
6604
 
6523
6605
  try {
6524
6606
  this._stopSendingStats(session);
@@ -6547,24 +6629,24 @@ class WebRTCClient extends Emitter {
6547
6629
 
6548
6630
  return bye();
6549
6631
  } catch (error) {
6550
- logger$8.warn('sdk webrtc hangup, error', error);
6632
+ logger$9.warn('sdk webrtc hangup, error', error);
6551
6633
  }
6552
6634
 
6553
6635
  return null;
6554
6636
  }
6555
6637
 
6556
6638
  reject(session ) {
6557
- logger$8.info('sdk webrtc reject call', { id: session.id });
6639
+ logger$9.info('sdk webrtc reject call', { id: session.id });
6558
6640
 
6559
6641
  try {
6560
6642
  return session.reject ? session.reject() : session.cancel();
6561
6643
  } catch (e) {
6562
- logger$8.warn('Error when rejecting call', e.message, e.stack);
6644
+ logger$9.warn('Error when rejecting call', e.message, e.stack);
6563
6645
  }
6564
6646
  }
6565
6647
 
6566
6648
  async close() {
6567
- logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6649
+ logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6568
6650
  this._cleanupMedia();
6569
6651
  this.connectionPromise = null;
6570
6652
 
@@ -6595,7 +6677,7 @@ class WebRTCClient extends Emitter {
6595
6677
  // eg: "INVITE not rejectable in state Completed"
6596
6678
  }
6597
6679
  this.userAgent = null;
6598
- logger$8.info('sdk webrtc client closed');
6680
+ logger$9.info('sdk webrtc client closed');
6599
6681
  }
6600
6682
 
6601
6683
  getNumber(session ) {
@@ -6608,13 +6690,13 @@ class WebRTCClient extends Emitter {
6608
6690
  }
6609
6691
 
6610
6692
  mute(session ) {
6611
- logger$8.info('sdk webrtc mute', { id: session.id });
6693
+ logger$9.info('sdk webrtc mute', { id: session.id });
6612
6694
 
6613
6695
  this._toggleAudio(session, true);
6614
6696
  }
6615
6697
 
6616
6698
  unmute(session ) {
6617
- logger$8.info('sdk webrtc unmute', { id: session.id });
6699
+ logger$9.info('sdk webrtc unmute', { id: session.id });
6618
6700
 
6619
6701
  this._toggleAudio(session, false);
6620
6702
  }
@@ -6631,12 +6713,18 @@ class WebRTCClient extends Emitter {
6631
6713
  }
6632
6714
 
6633
6715
  if (pc.getSenders) {
6716
+ if (!pc.getSenders().length) {
6717
+ return false;
6718
+ }
6634
6719
  pc.getSenders().forEach(sender => {
6635
6720
  if (sender && sender.track && sender.track.kind === 'audio') {
6636
6721
  muted = muted && !sender.track.enabled;
6637
6722
  }
6638
6723
  });
6639
6724
  } else {
6725
+ if (!pc.getLocalStreams().length) {
6726
+ return false;
6727
+ }
6640
6728
  pc.getLocalStreams().forEach(stream => {
6641
6729
  stream.getAudioTracks().forEach(track => {
6642
6730
  muted = muted && !track.enabled;
@@ -6648,20 +6736,20 @@ class WebRTCClient extends Emitter {
6648
6736
  }
6649
6737
 
6650
6738
  toggleCameraOn(session ) {
6651
- logger$8.info('sdk webrtc toggle camera on', { id: session.id });
6739
+ logger$9.info('sdk webrtc toggle camera on', { id: session.id });
6652
6740
 
6653
6741
  this._toggleVideo(session, false);
6654
6742
  }
6655
6743
 
6656
6744
  toggleCameraOff(session ) {
6657
- logger$8.info('sdk webrtc toggle camera off', { id: session.id });
6745
+ logger$9.info('sdk webrtc toggle camera off', { id: session.id });
6658
6746
 
6659
6747
  this._toggleVideo(session, true);
6660
6748
  }
6661
6749
 
6662
6750
  hold(session , isConference = false) {
6663
6751
  const sessionId = this.getSipSessionId(session);
6664
- logger$8.info('sdk webrtc hold', {
6752
+ logger$9.info('sdk webrtc hold', {
6665
6753
  sessionId,
6666
6754
  keys: Object.keys(this.heldSessions),
6667
6755
  pendingReinvite: !!session.pendingReinvite,
@@ -6695,6 +6783,8 @@ class WebRTCClient extends Emitter {
6695
6783
  }
6696
6784
  options.sessionDescriptionHandlerOptions = {
6697
6785
  constraints: options.constraints,
6786
+ hold: true,
6787
+ conference: isConference,
6698
6788
  };
6699
6789
 
6700
6790
  // Send re-INVITE
@@ -6704,7 +6794,7 @@ class WebRTCClient extends Emitter {
6704
6794
  unhold(session , isConference = false) {
6705
6795
  const sessionId = this.getSipSessionId(session);
6706
6796
 
6707
- logger$8.info('sdk webrtc unhold', {
6797
+ logger$9.info('sdk webrtc unhold', {
6708
6798
  sessionId,
6709
6799
  keys: Object.keys(this.heldSessions),
6710
6800
  pendingReinvite: !!session.pendingReinvite,
@@ -6737,6 +6827,8 @@ class WebRTCClient extends Emitter {
6737
6827
  }
6738
6828
  options.sessionDescriptionHandlerOptions = {
6739
6829
  constraints: options.constraints,
6830
+ hold: false,
6831
+ conference: isConference,
6740
6832
  };
6741
6833
 
6742
6834
  // Send re-INVITE
@@ -6795,7 +6887,7 @@ class WebRTCClient extends Emitter {
6795
6887
  return;
6796
6888
  }
6797
6889
 
6798
- logger$8.info('send WebRTC message', { sipId: sipSession.id, contentType });
6890
+ logger$9.info('send WebRTC message', { sipId: sipSession.id, contentType });
6799
6891
 
6800
6892
  try {
6801
6893
  sipSession.message({
@@ -6920,7 +7012,8 @@ class WebRTCClient extends Emitter {
6920
7012
  }
6921
7013
  const sdh = session.sessionDescriptionHandler;
6922
7014
  const pc = sdh.peerConnection;
6923
- const localStream = this.getLocalStream(this.getSipSessionId(session));
7015
+ const sessionId = this.getSipSessionId(session);
7016
+ const localStream = this.getLocalStream(sessionId);
6924
7017
 
6925
7018
  // Release old video stream
6926
7019
  if (localStream) {
@@ -6946,11 +7039,8 @@ class WebRTCClient extends Emitter {
6946
7039
 
6947
7040
  // let's update the local stream
6948
7041
  this.eventEmitter.emit('onVideoInputChange', stream);
6949
- try {
6950
- await sdh.setLocalMediaStream(stream);
6951
- } catch (_) {
6952
- // Nothing to do
6953
- }
7042
+ this.setLocalMediaStream(sessionId, stream);
7043
+
6954
7044
  return stream;
6955
7045
  });
6956
7046
  }
@@ -7162,7 +7252,7 @@ class WebRTCClient extends Emitter {
7162
7252
  }
7163
7253
 
7164
7254
  startHeartbeat() {
7165
- logger$8.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent });
7255
+ logger$9.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent });
7166
7256
  if (!this.userAgent) {
7167
7257
  this.heartbeat.stop();
7168
7258
  return;
@@ -7175,7 +7265,7 @@ class WebRTCClient extends Emitter {
7175
7265
  }
7176
7266
 
7177
7267
  stopHeartbeat() {
7178
- logger$8.info('sdk webrtc stop heartbeat');
7268
+ logger$9.info('sdk webrtc stop heartbeat');
7179
7269
  this.heartbeat.stop();
7180
7270
  }
7181
7271
 
@@ -7195,7 +7285,7 @@ class WebRTCClient extends Emitter {
7195
7285
  }
7196
7286
 
7197
7287
  attemptReconnection() {
7198
- logger$8.info('attempt reconnection', { userAgent: !!this.userAgent });
7288
+ logger$9.info('attempt reconnection', { userAgent: !!this.userAgent });
7199
7289
  if (!this.userAgent) {
7200
7290
  return;
7201
7291
  }
@@ -7252,9 +7342,11 @@ class WebRTCClient extends Emitter {
7252
7342
  remoteStream.removeTrack(track);
7253
7343
  });
7254
7344
 
7255
- pc.getReceivers().forEach(receiver => {
7256
- remoteStream.addTrack(receiver.track);
7257
- });
7345
+ if (pc.getReceivers) {
7346
+ pc.getReceivers().forEach(receiver => {
7347
+ remoteStream.addTrack(receiver.track);
7348
+ });
7349
+ }
7258
7350
  }
7259
7351
 
7260
7352
  getMediaConfiguration(enableVideo , conference = false, constraints = null) {
@@ -7289,6 +7381,25 @@ class WebRTCClient extends Emitter {
7289
7381
  return sessionId in this.conferences;
7290
7382
  }
7291
7383
 
7384
+ createAudioElementFor(sessionId ) {
7385
+ const audio = document.createElement('audio');
7386
+ audio.setAttribute('id', `audio-${sessionId}`);
7387
+
7388
+ if (audio.setSinkId && this.audioOutputDeviceId) {
7389
+ audio.setSinkId(this.audioOutputDeviceId);
7390
+ }
7391
+
7392
+ if (document.body) {
7393
+ document.body.appendChild(audio);
7394
+ }
7395
+ this.audioElements[sessionId] = audio;
7396
+
7397
+ audio.volume = this.audioOutputVolume;
7398
+ audio.autoplay = true;
7399
+
7400
+ return audio;
7401
+ }
7402
+
7292
7403
  _onTransportError() {
7293
7404
  this.eventEmitter.emit(TRANSPORT_ERROR);
7294
7405
  this.attemptReconnection();
@@ -7298,7 +7409,7 @@ class WebRTCClient extends Emitter {
7298
7409
  const body = message && typeof message === 'object' ? message.data : message;
7299
7410
  if (body && body.indexOf('200 OK') !== -1) {
7300
7411
  if (this.hasHeartbeat()) {
7301
- logger$8.info('on heartbeat received from Asterisk', { hasHeartbeat: this.hasHeartbeat() });
7412
+ logger$9.info('on heartbeat received from Asterisk', { hasHeartbeat: this.hasHeartbeat() });
7302
7413
 
7303
7414
  this.heartbeat.onHeartbeat();
7304
7415
  if (this.heartbeatCb) {
@@ -7309,7 +7420,7 @@ class WebRTCClient extends Emitter {
7309
7420
  }
7310
7421
 
7311
7422
  async _onHeartbeatTimeout() {
7312
- logger$8.info('sdk webrtc heartbeat timed out', { userAgent: !!this.userAgent, cb: !!this.heartbeatTimeoutCb });
7423
+ logger$9.info('sdk webrtc heartbeat timed out', { userAgent: !!this.userAgent, cb: !!this.heartbeatTimeoutCb });
7313
7424
 
7314
7425
  if (this.heartbeatTimeoutCb) {
7315
7426
  this.heartbeatTimeoutCb();
@@ -7321,7 +7432,7 @@ class WebRTCClient extends Emitter {
7321
7432
  try {
7322
7433
  await this.userAgent.transport.disconnect();
7323
7434
  } catch (e) {
7324
- logger$8.error('Transport disconnection after heartbeat timeout, error', e);
7435
+ logger$9.error('Transport disconnection after heartbeat timeout, error', e);
7325
7436
  }
7326
7437
  }
7327
7438
 
@@ -7354,31 +7465,31 @@ class WebRTCClient extends Emitter {
7354
7465
  }
7355
7466
 
7356
7467
  _connectIfNeeded() {
7357
- logger$8.info('connect if needed, checking', { connected: this.isConnected() });
7468
+ logger$9.info('connect if needed, checking', { connected: this.isConnected() });
7358
7469
  if (!this.userAgent) {
7359
- logger$8.info('need to recreate User Agent');
7470
+ logger$9.info('need to recreate User Agent');
7360
7471
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
7361
7472
  }
7362
7473
 
7363
7474
  if (this.isConnected()) {
7364
- logger$8.info('webrtc sdk, already connected');
7475
+ logger$9.info('webrtc sdk, already connected');
7365
7476
  return Promise.resolve();
7366
7477
  }
7367
7478
 
7368
7479
  if (this.isConnecting()) {
7369
- logger$8.info('webrtc sdk, already connecting...');
7480
+ logger$9.info('webrtc sdk, already connecting...');
7370
7481
 
7371
7482
  this.connectionPromise = this.userAgent.transport.connectPromise;
7372
7483
  return this.connectionPromise;
7373
7484
  }
7374
7485
 
7375
7486
  if (this.connectionPromise) {
7376
- logger$8.info('webrtc sdk, connection promise connecting...');
7487
+ logger$9.info('webrtc sdk, connection promise connecting...');
7377
7488
  // $FlowFixMe
7378
7489
  return this.connectionPromise;
7379
7490
  }
7380
7491
 
7381
- logger$8.info('WebRTC UA needs to connect');
7492
+ logger$9.info('WebRTC UA needs to connect');
7382
7493
 
7383
7494
  // Force UA to reconnect
7384
7495
  if (this.userAgent && this.userAgent.state !== userAgentState.UserAgentState.Stopped) {
@@ -7503,7 +7614,7 @@ class WebRTCClient extends Emitter {
7503
7614
 
7504
7615
  sdh.peerConnectionDelegate = {
7505
7616
  onicecandidateerror: (error ) => {
7506
- logger$8.error('on icecandidate error', {
7617
+ logger$9.error('on icecandidate error', {
7507
7618
  address: error.address,
7508
7619
  port: error.port,
7509
7620
  errorCode: error.errorCode,
@@ -7518,7 +7629,7 @@ class WebRTCClient extends Emitter {
7518
7629
  let hadRemoteVideo = false;
7519
7630
 
7520
7631
  // Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
7521
- // Becase when `onInvite` is called we already got the video track
7632
+ // Because when `onInvite` is called we already got the video track
7522
7633
  session.onInviteRequest = (request) => {
7523
7634
  hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
7524
7635
 
@@ -7532,7 +7643,7 @@ class WebRTCClient extends Emitter {
7532
7643
  updatedNumber = session.assertedIdentity.uri.normal.user;
7533
7644
  updatedCalleeName = session.assertedIdentity.displayName || updatedNumber;
7534
7645
  }
7535
- logger$8.info('re-invite received', { updatedCalleeName, updatedNumber });
7646
+ logger$9.info('re-invite received', { updatedCalleeName, updatedNumber });
7536
7647
 
7537
7648
  // Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
7538
7649
 
@@ -7553,7 +7664,7 @@ class WebRTCClient extends Emitter {
7553
7664
  }
7554
7665
 
7555
7666
  _onAccepted(session , sessionDialog , withEvent = true) {
7556
- logger$8.info('on call accepted', { id: session.id, remoteTag: session.remoteTag });
7667
+ logger$9.info('on call accepted', { id: session.id, remoteTag: session.remoteTag });
7557
7668
 
7558
7669
  this.storeSipSession(session);
7559
7670
 
@@ -7593,20 +7704,10 @@ class WebRTCClient extends Emitter {
7593
7704
  const isConference = this.isConference(sessionId);
7594
7705
 
7595
7706
  if (this._hasAudio() && this._isWeb() && !(sessionId in this.audioElements)) {
7596
- const audio = document.createElement('audio');
7597
- audio.setAttribute('id', `audio-${sessionId}`);
7598
-
7599
- if (audio.setSinkId && this.audioOutputDeviceId) {
7600
- audio.setSinkId(this.audioOutputDeviceId);
7601
- }
7602
-
7603
- if (document.body) {
7604
- document.body.appendChild(audio);
7605
- }
7606
- this.audioElements[sessionId] = audio;
7707
+ this.createAudioElementFor(sessionId);
7607
7708
  }
7608
7709
 
7609
- const audioElement = this.audioElements[this.getSipSessionId(session)];
7710
+ const audioElement = this.audioElements[sessionId];
7610
7711
  const stream = newStream || this.getRemoteStream(sessionId);
7611
7712
 
7612
7713
  if (!this._isWeb() || !stream) {
@@ -7753,10 +7854,10 @@ class WebRTCClient extends Emitter {
7753
7854
 
7754
7855
  _stopSendingStats(session ) {
7755
7856
  const sessionId = this.getSipSessionId(session);
7756
- logger$8.trace('Check for stopping stats', { sessionId, ids: Object.keys(this.statsIntervals) });
7857
+ logger$9.trace('Check for stopping stats', { sessionId, ids: Object.keys(this.statsIntervals) });
7757
7858
 
7758
7859
  if (sessionId in this.statsIntervals) {
7759
- logger$8.trace('Stop sending stats for call', { sessionId });
7860
+ logger$9.trace('Stop sending stats for call', { sessionId });
7760
7861
  this.statsIntervals[sessionId]();
7761
7862
  delete this.statsIntervals[sessionId];
7762
7863
  }
@@ -7772,7 +7873,7 @@ class WebRTCClient extends Emitter {
7772
7873
  try {
7773
7874
  await this.userAgent.transport.disconnect();
7774
7875
  } catch (e) {
7775
- logger$8.error('WebRTC transport disconnect, error', e);
7876
+ logger$9.error('WebRTC transport disconnect, error', e);
7776
7877
  }
7777
7878
  }
7778
7879
  }
@@ -7859,7 +7960,7 @@ const events = [
7859
7960
  ON_SIGNAL,
7860
7961
  ];
7861
7962
 
7862
- const logger$7 = IssueReporter$1.loggerFor('webrtc-phone');
7963
+ const logger$8 = IssueReporter$1.loggerFor('webrtc-phone');
7863
7964
 
7864
7965
  class WebRTCPhone extends Emitter {
7865
7966
 
@@ -7930,7 +8031,7 @@ class WebRTCPhone extends Emitter {
7930
8031
  }).catch(error => {
7931
8032
  // Avoid exception on `t.server.scheme` in sip transport when losing the webrtc socket connection
7932
8033
  console.error('register error', error, error.message, error.stack);
7933
- logger$7.error('WebRTC register error', { message: error.message, stack: error.stack });
8034
+ logger$8.error('WebRTC register error', { message: error.message, stack: error.stack });
7934
8035
  });
7935
8036
  }
7936
8037
 
@@ -7945,7 +8046,7 @@ class WebRTCPhone extends Emitter {
7945
8046
  if (!this.client) {
7946
8047
  return;
7947
8048
  }
7948
- logger$7.info('WebRTC phone stop');
8049
+ logger$8.info('WebRTC phone stop');
7949
8050
  this.client.stop();
7950
8051
  }
7951
8052
 
@@ -7960,14 +8061,14 @@ class WebRTCPhone extends Emitter {
7960
8061
  async sendReinvite(callSession , constraints = null, conference = false,
7961
8062
  audioOnly = false) {
7962
8063
  const sipSession = this.findSipSession(callSession);
7963
- logger$7.info('WebRTC phone - send reinvite', {
8064
+ logger$8.info('WebRTC phone - send reinvite', {
7964
8065
  sessionId: sipSession ? sipSession.id : null,
7965
8066
  constraints,
7966
8067
  audioOnly,
7967
8068
  });
7968
8069
 
7969
8070
  if (!sipSession) {
7970
- return null;
8071
+ return false;
7971
8072
  }
7972
8073
 
7973
8074
  // $FlowFixMe
@@ -7977,19 +8078,17 @@ class WebRTCPhone extends Emitter {
7977
8078
  // Downgrade
7978
8079
  if (constraints && !isUpgrade) {
7979
8080
  // No reinvite needed
7980
- return this._downgradeToAudio(callSession);
8081
+ this._downgradeToAudio(callSession);
8082
+ return false;
7981
8083
  }
7982
8084
 
7983
8085
  if (isUpgrade) {
7984
8086
  const shouldReinvite = await this._upgradeToVideo(callSession, constraints, conference);
7985
8087
  if (!shouldReinvite) {
7986
- return;
8088
+ return false;
7987
8089
  }
7988
8090
  }
7989
8091
 
7990
- // Force reinvite in SDH
7991
- sipSession.sessionDescriptionHandler.localMediaStreamConstraints = null;
7992
-
7993
8092
  return this.client.reinvite(sipSession, constraints, conference, audioOnly);
7994
8093
  }
7995
8094
 
@@ -7998,7 +8097,7 @@ class WebRTCPhone extends Emitter {
7998
8097
  }
7999
8098
 
8000
8099
  startHeartbeat() {
8001
- logger$7.info('WebRTC phone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client.hasHeartbeat() });
8100
+ logger$8.info('WebRTC phone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client.hasHeartbeat() });
8002
8101
  if (!this.client || this.client.hasHeartbeat()) {
8003
8102
  return;
8004
8103
  }
@@ -8007,7 +8106,7 @@ class WebRTCPhone extends Emitter {
8007
8106
  }
8008
8107
 
8009
8108
  stopHeartbeat() {
8010
- logger$7.info('WebRTC phone - stopHeartbeat', { client: !!this.client });
8109
+ logger$8.info('WebRTC phone - stopHeartbeat', { client: !!this.client });
8011
8110
  if (!this.client) {
8012
8111
  return;
8013
8112
  }
@@ -8024,7 +8123,7 @@ class WebRTCPhone extends Emitter {
8024
8123
  }
8025
8124
 
8026
8125
  reconnect() {
8027
- logger$7.info('WebRTC phone - reconnect', { client: !!this.client });
8126
+ logger$8.info('WebRTC phone - reconnect', { client: !!this.client });
8028
8127
  if (!this.client) {
8029
8128
  return;
8030
8129
  }
@@ -8062,7 +8161,7 @@ class WebRTCPhone extends Emitter {
8062
8161
  _downgradeToAudio(callSession ) {
8063
8162
  const sipSession = this.findSipSession(callSession);
8064
8163
  if (!sipSession) {
8065
- return;
8164
+ return false;
8066
8165
  }
8067
8166
 
8068
8167
  // Release local video stream when downgrading to audio
@@ -8175,7 +8274,7 @@ class WebRTCPhone extends Emitter {
8175
8274
  // Monkey patch to know when canceled with the CANCEL message
8176
8275
  const onCancel = sipSession._onCancel.bind(sipSession);
8177
8276
  sipSession._onCancel = (message ) => {
8178
- logger$7.trace('on sip session canceled', { callId: message.callId });
8277
+ logger$8.trace('on sip session canceled', { callId: message.callId });
8179
8278
 
8180
8279
  onCancel(message);
8181
8280
  const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
@@ -8200,13 +8299,13 @@ class WebRTCPhone extends Emitter {
8200
8299
  this.audioOutputVolume,
8201
8300
  );
8202
8301
  case sessionState.SessionState.Terminating:
8203
- logger$7.info('WebRTC phone - call terminating', { sipId: sipSession.id });
8302
+ logger$8.info('WebRTC phone - call terminating', { sipId: sipSession.id });
8204
8303
 
8205
8304
  this.eventEmitter.emit(ON_CALL_ENDING, this._createCallSession(sipSession));
8206
8305
 
8207
8306
  break;
8208
8307
  case sessionState.SessionState.Terminated:
8209
- logger$7.info('WebRTC phone - call terminated', { sipId: sipSession.id });
8308
+ logger$8.info('WebRTC phone - call terminated', { sipId: sipSession.id });
8210
8309
 
8211
8310
  this._onCallTerminated(sipSession);
8212
8311
 
@@ -8242,7 +8341,7 @@ class WebRTCPhone extends Emitter {
8242
8341
  }
8243
8342
 
8244
8343
  async startScreenSharing(constraints , callSession ) {
8245
- logger$7.info('WebRTC - start screen sharing', { constraints, id: callSession ? callSession.getId() : null });
8344
+ logger$8.info('WebRTC - start screen sharing', { constraints, id: callSession ? callSession.getId() : null });
8246
8345
 
8247
8346
  const screenShareStream = await this._getStreamFromConstraints(constraints);
8248
8347
  if (!screenShareStream) {
@@ -8264,6 +8363,10 @@ class WebRTCPhone extends Emitter {
8264
8363
  localStream.removeTrack(videoTrack);
8265
8364
  }
8266
8365
 
8366
+ if (localStream) {
8367
+ localStream.addTrack(screenTrack);
8368
+ }
8369
+
8267
8370
  if (sender) {
8268
8371
  sender.replaceTrack(screenTrack);
8269
8372
  }
@@ -8278,7 +8381,8 @@ class WebRTCPhone extends Emitter {
8278
8381
  return;
8279
8382
  }
8280
8383
 
8281
- logger$7.info('WebRTC phone - stop screen sharing');
8384
+ logger$8.info('WebRTC phone - stop screen sharing');
8385
+ let reinvited = false;
8282
8386
 
8283
8387
  try {
8284
8388
  if (this.currentScreenShare.stream) {
@@ -8293,7 +8397,8 @@ class WebRTCPhone extends Emitter {
8293
8397
  // When upgrading directly to screenshare (eg: we don't have a videoLocalStream to replace)
8294
8398
  // We have to downgrade to audio.
8295
8399
  const screenshareStopped = this.currentScreenShare.sender && this.currentScreenShare.hadVideo;
8296
- await this.sendReinvite(targetCallSession, { audio: false, video: screenshareStopped }, conference);
8400
+ const constraints = { audio: false, video: screenshareStopped };
8401
+ reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
8297
8402
  }
8298
8403
  } catch (e) {
8299
8404
  console.warn(e);
@@ -8307,6 +8412,8 @@ class WebRTCPhone extends Emitter {
8307
8412
  );
8308
8413
 
8309
8414
  this.currentScreenShare = null;
8415
+
8416
+ return reinvited;
8310
8417
  }
8311
8418
 
8312
8419
  async _getStreamFromConstraints(constraints , conference = false) {
@@ -8344,7 +8451,7 @@ class WebRTCPhone extends Emitter {
8344
8451
  }
8345
8452
 
8346
8453
  _onCallAccepted(sipSession , cameraEnabled ) {
8347
- logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
8454
+ logger$8.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
8348
8455
 
8349
8456
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
8350
8457
  this.currentSipSession = sipSession;
@@ -8362,11 +8469,15 @@ class WebRTCPhone extends Emitter {
8362
8469
  }
8363
8470
 
8364
8471
  changeAudioDevice(id ) {
8365
- logger$7.info('WebRTC phone - change audio device', { deviceId: id });
8472
+ logger$8.info('WebRTC phone - change audio device', { deviceId: id });
8366
8473
  this.audioOutputDeviceId = id;
8367
8474
  this.client.changeAudioOutputDevice(id);
8368
8475
  }
8369
8476
 
8477
+ createAudioElementFor(sessionId ) {
8478
+ return this.client.createAudioElementFor(sessionId);
8479
+ }
8480
+
8370
8481
  changeRingDevice(id ) {
8371
8482
  this.audioRingDeviceId = id;
8372
8483
  }
@@ -8383,25 +8494,25 @@ class WebRTCPhone extends Emitter {
8383
8494
  }
8384
8495
 
8385
8496
  changeAudioInputDevice(id ) {
8386
- logger$7.info('WebRTC phone - changeAudio input device', { deviceId: id });
8497
+ logger$8.info('WebRTC phone - changeAudio input device', { deviceId: id });
8387
8498
 
8388
8499
  return this.client.changeAudioInputDevice(id, this.currentSipSession);
8389
8500
  }
8390
8501
 
8391
8502
  changeVideoInputDevice(id ) {
8392
- logger$7.info('WebRTC phone - change video input device', { deviceId: id });
8503
+ logger$8.info('WebRTC phone - change video input device', { deviceId: id });
8393
8504
 
8394
8505
  return this.client.changeVideoInputDevice(id, this.currentSipSession);
8395
8506
  }
8396
8507
 
8397
8508
  changeSessionVideoInputDevice(id ) {
8398
- logger$7.info('WebRTC phone - change session video input device', { deviceId: id });
8509
+ logger$8.info('WebRTC phone - change session video input device', { deviceId: id });
8399
8510
 
8400
8511
  return this.client.changeSessionVideoInputDevice(id, this.currentSipSession);
8401
8512
  }
8402
8513
 
8403
8514
  _onCallTerminated(sipSession ) {
8404
- logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
8515
+ logger$8.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
8405
8516
 
8406
8517
  const callSession = this._createCallSession(sipSession);
8407
8518
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
@@ -8435,7 +8546,7 @@ class WebRTCPhone extends Emitter {
8435
8546
  const hasIncomingCallSession = this.hasIncomingCallSession();
8436
8547
 
8437
8548
  // Re-trigger incoming call event for remaining incoming calls
8438
- logger$7.info('WebRTC phone - check to re-trigger incoming call', {
8549
+ logger$8.info('WebRTC phone - check to re-trigger incoming call', {
8439
8550
  sipId: sipSession.id,
8440
8551
  shouldRetrigger,
8441
8552
  hasIncomingCallSession,
@@ -8524,37 +8635,37 @@ class WebRTCPhone extends Emitter {
8524
8635
 
8525
8636
  // Deprecated
8526
8637
  getLocalStreamForCall(callSession ) {
8527
- logger$7.warn('WebRTCPhone.getLocalStreamForCall is deprecated, use WebRTCPhone.getLocalStream instead');
8638
+ logger$8.warn('WebRTCPhone.getLocalStreamForCall is deprecated, use WebRTCPhone.getLocalStream instead');
8528
8639
 
8529
8640
  return this.getLocalStream(callSession);
8530
8641
  }
8531
8642
 
8532
8643
  // Deprecated
8533
8644
  getRemoteStreamForCall(callSession ) {
8534
- logger$7.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
8645
+ logger$8.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
8535
8646
 
8536
8647
  return this.getRemoteVideoStream(callSession);
8537
8648
  }
8538
8649
 
8539
8650
  getRemoteStreamsForCall(callSession ) {
8540
- logger$7.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
8651
+ logger$8.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
8541
8652
 
8542
8653
  return this.getRemoteStream(callSession);
8543
8654
  }
8544
8655
 
8545
8656
  accept(callSession , cameraEnabled ) {
8546
- logger$7.info('WebRTC phone - accept call', { id: callSession ? callSession.getId() : 'n/a', cameraEnabled });
8657
+ logger$8.info('WebRTC phone - accept call', { id: callSession ? callSession.getId() : 'n/a', cameraEnabled });
8547
8658
  if (this.currentSipSession) {
8548
8659
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true);
8549
8660
  }
8550
8661
 
8551
8662
  if (!callSession) {
8552
- logger$7.warn('no CallSession to accept.');
8663
+ logger$8.warn('no CallSession to accept.');
8553
8664
  return Promise.resolve(null);
8554
8665
  }
8555
8666
 
8556
8667
  if (callSession.getId() in this.acceptedSessions) {
8557
- logger$7.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
8668
+ logger$8.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
8558
8669
  return Promise.resolve(callSession.sipCallId);
8559
8670
  }
8560
8671
 
@@ -8566,24 +8677,24 @@ class WebRTCPhone extends Emitter {
8566
8677
  const sipSession = this.client.getSipSession(callSession.getId());
8567
8678
  if (sipSession) {
8568
8679
  if (sipSession.state === sessionState.SessionState.Terminated || sipSession.state === sessionState.SessionState.Terminating) {
8569
- logger$7.warn('Trying to answer a terminated sipSession.');
8680
+ logger$8.warn('Trying to answer a terminated sipSession.');
8570
8681
 
8571
8682
  return Promise.resolve(null);
8572
8683
  }
8573
8684
 
8574
- logger$7.info('accept call, session found', { sipId: sipSession.id });
8685
+ logger$8.info('accept call, session found', { sipId: sipSession.id });
8575
8686
 
8576
8687
  // $FlowFixMe
8577
8688
  return this.client.answer(sipSession, this.allowVideo ? cameraEnabled : false).then(() => {
8578
8689
  return callSession.sipCallId;
8579
8690
  }).catch(e => {
8580
- logger$7.error(e);
8691
+ logger$8.error(e);
8581
8692
  this.endCurrentCall(callSession);
8582
8693
  throw e;
8583
8694
  });
8584
8695
  }
8585
8696
 
8586
- logger$7.warn('no CallSession found to accept.', { id: callSession ? callSession.getId() : 'n/a' });
8697
+ logger$8.warn('no CallSession found to accept.', { id: callSession ? callSession.getId() : 'n/a' });
8587
8698
 
8588
8699
  return Promise.resolve(null);
8589
8700
  }
@@ -8593,7 +8704,7 @@ class WebRTCPhone extends Emitter {
8593
8704
  }
8594
8705
 
8595
8706
  async reject(callSession ) {
8596
- logger$7.info('reject WebRTC called', { id: callSession.getId() });
8707
+ logger$8.info('reject WebRTC called', { id: callSession.getId() });
8597
8708
 
8598
8709
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'call rejected locally');
8599
8710
  if (!callSession || callSession.getId() in this.rejectedSessions) {
@@ -8605,14 +8716,14 @@ class WebRTCPhone extends Emitter {
8605
8716
 
8606
8717
  const sipSession = this.findSipSession(callSession);
8607
8718
  if (sipSession) {
8608
- logger$7.info('WebRTC rejecting', { sipId: sipSession.id });
8719
+ logger$8.info('WebRTC rejecting', { sipId: sipSession.id });
8609
8720
 
8610
8721
  this.client.hangup(sipSession);
8611
8722
  }
8612
8723
  }
8613
8724
 
8614
8725
  async ignore(callSession ) {
8615
- logger$7.info('WebRTC ignore', { id: callSession.getId() });
8726
+ logger$8.info('WebRTC ignore', { id: callSession.getId() });
8616
8727
 
8617
8728
  // kill the ring
8618
8729
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'ignoring call');
@@ -8621,7 +8732,7 @@ class WebRTCPhone extends Emitter {
8621
8732
  }
8622
8733
 
8623
8734
  hold(callSession , withEvent = true, isConference = false) {
8624
- logger$7.info('WebRTC hold', { id: callSession.getId() });
8735
+ logger$8.info('WebRTC hold', { id: callSession.getId() });
8625
8736
 
8626
8737
  const sipSession = this.findSipSession(callSession);
8627
8738
 
@@ -8632,7 +8743,7 @@ class WebRTCPhone extends Emitter {
8632
8743
 
8633
8744
  // @Deprecated
8634
8745
  unhold(callSession , withEvent = true, isConference = false) {
8635
- logger$7.info('WebRTC unhold', { id: callSession ? callSession.getId() : null });
8746
+ logger$8.info('WebRTC unhold', { id: callSession ? callSession.getId() : null });
8636
8747
 
8637
8748
  console.warn('Please note that `phone.unhold()` is being deprecated; `phone.resume()` is the preferred method');
8638
8749
 
@@ -8647,7 +8758,7 @@ class WebRTCPhone extends Emitter {
8647
8758
  const sipSession = this.findSipSession(callSession);
8648
8759
 
8649
8760
  if (sipSession) {
8650
- logger$7.info('WebRTC atxfer', { sipId: sipSession.id });
8761
+ logger$8.info('WebRTC atxfer', { sipId: sipSession.id });
8651
8762
 
8652
8763
  return this.client.atxfer(sipSession);
8653
8764
  }
@@ -8662,7 +8773,7 @@ class WebRTCPhone extends Emitter {
8662
8773
  if (!sipSession) {
8663
8774
  return new Promise((resolve, reject) => reject(new Error('No session to hold')));
8664
8775
  }
8665
- logger$7.info('WebRTC hold sip session', { sipId: sipSession.id });
8776
+ logger$8.info('WebRTC hold sip session', { sipId: sipSession.id });
8666
8777
 
8667
8778
  const promise = this.client.hold(sipSession, isConference);
8668
8779
  if (withEvent) {
@@ -8681,7 +8792,7 @@ class WebRTCPhone extends Emitter {
8681
8792
  if (!sipSession) {
8682
8793
  return new Promise((resolve, reject) => reject(new Error('No session to unhold')));
8683
8794
  }
8684
- logger$7.info('WebRTC unhold', { sipId: sipSession.id });
8795
+ logger$8.info('WebRTC unhold', { sipId: sipSession.id });
8685
8796
 
8686
8797
  const promise = this.client.unhold(sipSession, isConference);
8687
8798
  if (withEvent) {
@@ -8692,18 +8803,18 @@ class WebRTCPhone extends Emitter {
8692
8803
  }
8693
8804
 
8694
8805
  resume(callSession , isConference = false) {
8695
- logger$7.info('WebRTC resume called', { id: callSession ? callSession.getId() : null });
8806
+ logger$8.info('WebRTC resume called', { id: callSession ? callSession.getId() : null });
8696
8807
 
8697
8808
  const sipSession = this.findSipSession(callSession);
8698
8809
  if (!sipSession) {
8699
8810
  return new Promise((resolve, reject) => reject(new Error('No session to resume')));
8700
8811
  }
8701
8812
 
8702
- logger$7.info('WebRTC resuming', { sipId: sipSession.id });
8813
+ logger$8.info('WebRTC resuming', { sipId: sipSession.id });
8703
8814
 
8704
8815
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
8705
8816
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
8706
- logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
8817
+ logger$8.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
8707
8818
  this.holdSipSession(this.currentSipSession, callSession);
8708
8819
  }
8709
8820
 
@@ -8718,14 +8829,14 @@ class WebRTCPhone extends Emitter {
8718
8829
  }
8719
8830
 
8720
8831
  mute(callSession , withEvent = true) {
8721
- logger$7.info('WebRTC mute called', { id: callSession ? callSession.getId() : null });
8832
+ logger$8.info('WebRTC mute called', { id: callSession ? callSession.getId() : null });
8722
8833
 
8723
8834
  const sipSession = this.findSipSession(callSession);
8724
8835
  if (!sipSession) {
8725
8836
  return;
8726
8837
  }
8727
8838
 
8728
- logger$7.info('WebRTC muting', { sipId: sipSession.id });
8839
+ logger$8.info('WebRTC muting', { sipId: sipSession.id });
8729
8840
  this.client.mute(sipSession);
8730
8841
  const newCallSession = this._createCallSession(sipSession, callSession, { muted: true });
8731
8842
 
@@ -8739,14 +8850,14 @@ class WebRTCPhone extends Emitter {
8739
8850
  }
8740
8851
 
8741
8852
  unmute(callSession , withEvent = true) {
8742
- logger$7.info('WebRTC unmute called', { id: callSession ? callSession.getId() : null });
8853
+ logger$8.info('WebRTC unmute called', { id: callSession ? callSession.getId() : null });
8743
8854
 
8744
8855
  const sipSession = this.findSipSession(callSession);
8745
8856
  if (!sipSession) {
8746
8857
  return;
8747
8858
  }
8748
8859
 
8749
- logger$7.info('WebRTC unmuting', { sipId: sipSession.id });
8860
+ logger$8.info('WebRTC unmuting', { sipId: sipSession.id });
8750
8861
  this.client.unmute(sipSession);
8751
8862
  const newCallSession = this._createCallSession(sipSession, callSession, { muted: false });
8752
8863
 
@@ -8773,7 +8884,7 @@ class WebRTCPhone extends Emitter {
8773
8884
  if (!sipSession) {
8774
8885
  return;
8775
8886
  }
8776
- logger$7.info('WebRTC turn camera on', { sipId: sipSession.id });
8887
+ logger$8.info('WebRTC turn camera on', { sipId: sipSession.id });
8777
8888
 
8778
8889
  this.client.toggleCameraOn(sipSession);
8779
8890
 
@@ -8785,7 +8896,7 @@ class WebRTCPhone extends Emitter {
8785
8896
  if (!sipSession) {
8786
8897
  return;
8787
8898
  }
8788
- logger$7.info('WebRTC turn camera off', { sipId: sipSession.id });
8899
+ logger$8.info('WebRTC turn camera off', { sipId: sipSession.id });
8789
8900
 
8790
8901
  this.client.toggleCameraOff(sipSession);
8791
8902
  this.eventEmitter.emit(ON_CAMERA_DISABLED, this._createCameraDisabledCallSession(sipSession, callSession));
@@ -8797,7 +8908,7 @@ class WebRTCPhone extends Emitter {
8797
8908
  return;
8798
8909
  }
8799
8910
 
8800
- logger$7.info('WebRTC send key', { sipId: sipSession.id, tone });
8911
+ logger$8.info('WebRTC send key', { sipId: sipSession.id, tone });
8801
8912
  this.client.sendDTMF(sipSession, tone);
8802
8913
  }
8803
8914
 
@@ -8805,7 +8916,7 @@ class WebRTCPhone extends Emitter {
8805
8916
  // @TODO: line is not used here
8806
8917
  async makeCall(number , line , cameraEnabled ,
8807
8918
  audioOnly = false, conference = false) {
8808
- logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
8919
+ logger$8.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
8809
8920
  if (!number) {
8810
8921
  return Promise.resolve(null);
8811
8922
  }
@@ -8815,7 +8926,7 @@ class WebRTCPhone extends Emitter {
8815
8926
  }
8816
8927
  if (this.currentSipSession) {
8817
8928
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true).catch(e => {
8818
- logger$7.warn('Unable to hold current session when making another call', e);
8929
+ logger$8.warn('Unable to hold current session when making another call', e);
8819
8930
  });
8820
8931
  }
8821
8932
 
@@ -8825,7 +8936,7 @@ class WebRTCPhone extends Emitter {
8825
8936
  this._bindEvents(sipSession);
8826
8937
  } catch (error) {
8827
8938
  console.warn(error);
8828
- logger$7.warn('make WebRTC call, error', { message: error.message, stack: error.stack });
8939
+ logger$8.warn('make WebRTC call, error', { message: error.message, stack: error.stack });
8829
8940
  return Promise.resolve(null);
8830
8941
  }
8831
8942
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
@@ -8853,7 +8964,7 @@ class WebRTCPhone extends Emitter {
8853
8964
  return;
8854
8965
  }
8855
8966
 
8856
- logger$7.info('WebRTC transfer', { sipId: sipSession.id, target });
8967
+ logger$8.info('WebRTC transfer', { sipId: sipSession.id, target });
8857
8968
 
8858
8969
  this.client.transfer(sipSession, target);
8859
8970
  }
@@ -8862,7 +8973,7 @@ class WebRTCPhone extends Emitter {
8862
8973
  const sipSession = this.client.getSipSession(source.sipCallId);
8863
8974
  const sipSessionTarget = this.client.getSipSession(destination.sipCallId);
8864
8975
 
8865
- logger$7.info('WebRTC indirect transfer', {
8976
+ logger$8.info('WebRTC indirect transfer', {
8866
8977
  sipId: sipSession ? sipSession.id : null,
8867
8978
  target: sipSessionTarget ? sipSessionTarget.id : null,
8868
8979
  });
@@ -8890,7 +9001,7 @@ class WebRTCPhone extends Emitter {
8890
9001
  return false;
8891
9002
  }
8892
9003
 
8893
- logger$7.info('WebRTC hangup', { sipId: sipSession.id });
9004
+ logger$8.info('WebRTC hangup', { sipId: sipSession.id });
8894
9005
 
8895
9006
  const sipSessionId = this.getSipSessionId(sipSession);
8896
9007
 
@@ -8935,7 +9046,7 @@ class WebRTCPhone extends Emitter {
8935
9046
  }
8936
9047
 
8937
9048
  async close() {
8938
- logger$7.info('WebRTC close');
9049
+ logger$8.info('WebRTC close');
8939
9050
 
8940
9051
  try {
8941
9052
  await Promise.race([
@@ -8943,7 +9054,7 @@ class WebRTCPhone extends Emitter {
8943
9054
  new Promise((resolve, reject) => setTimeout(() => reject(new Error('Unregister, timed out')), 3000)),
8944
9055
  ]);
8945
9056
  } catch (e) {
8946
- logger$7.error('WebRTC close, unregister error', e);
9057
+ logger$8.error('WebRTC close, unregister error', e);
8947
9058
  }
8948
9059
 
8949
9060
  this.client.close();
@@ -8961,12 +9072,12 @@ class WebRTCPhone extends Emitter {
8961
9072
  }
8962
9073
 
8963
9074
  enableRinging() {
8964
- logger$7.info('WebRTC enable ringing');
9075
+ logger$8.info('WebRTC enable ringing');
8965
9076
  this.ringingEnabled = true;
8966
9077
  }
8967
9078
 
8968
9079
  disableRinging() {
8969
- logger$7.info('WebRTC disable ringing');
9080
+ logger$8.info('WebRTC disable ringing');
8970
9081
  this.ringingEnabled = false;
8971
9082
  }
8972
9083
 
@@ -9006,7 +9117,7 @@ class WebRTCPhone extends Emitter {
9006
9117
 
9007
9118
  // Deprecated
9008
9119
  getLocalMediaStream(callSession ) {
9009
- logger$7.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
9120
+ logger$8.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
9010
9121
  return this.getLocalStream(callSession);
9011
9122
  }
9012
9123
 
@@ -9014,6 +9125,10 @@ class WebRTCPhone extends Emitter {
9014
9125
  return callSession ? this.client.hasLocalVideo(callSession.sipCallId) : null;
9015
9126
  }
9016
9127
 
9128
+ hasALocalVideoTrack(callSession ) {
9129
+ return callSession ? this.client.hasALocalVideoTrack(callSession.sipCallId) : null;
9130
+ }
9131
+
9017
9132
  getRemoteStream(callSession ) {
9018
9133
  return callSession ? this.client.getRemoteStream(callSession.sipCallId) : null;
9019
9134
  }
@@ -9036,7 +9151,7 @@ class WebRTCPhone extends Emitter {
9036
9151
  this.client.on(this.client.INVITE, (sipSession , wantsToDoVideo ) => {
9037
9152
  const autoAnswer = sipSession.request.getHeader('Answer-Mode') === 'Auto';
9038
9153
  const withVideo = this.allowVideo ? wantsToDoVideo : false;
9039
- logger$7.info('WebRTC invite received', { sipId: sipSession.id, withVideo, autoAnswer });
9154
+ logger$8.info('WebRTC invite received', { sipId: sipSession.id, withVideo, autoAnswer });
9040
9155
 
9041
9156
  const callSession = this._createIncomingCallSession(sipSession, withVideo, null, autoAnswer);
9042
9157
  this.incomingSessions.push(callSession.getId());
@@ -9059,7 +9174,7 @@ class WebRTCPhone extends Emitter {
9059
9174
  });
9060
9175
 
9061
9176
  this.client.on(this.client.ON_REINVITE, (...args) => {
9062
- logger$7.info('WebRTC on reinvite', {
9177
+ logger$8.info('WebRTC on reinvite', {
9063
9178
  sessionId: args[0].id,
9064
9179
  inviteId: args[1].id,
9065
9180
  updatedCalleeName: args[2],
@@ -9079,7 +9194,7 @@ class WebRTCPhone extends Emitter {
9079
9194
  });
9080
9195
 
9081
9196
  this.client.on(this.client.ACCEPTED, (sipSession ) => {
9082
- logger$7.info('WebRTC call accepted', { sipId: sipSession.id });
9197
+ logger$8.info('WebRTC call accepted', { sipId: sipSession.id });
9083
9198
 
9084
9199
  this._onCallAccepted(sipSession, this.client.hasVideo(this.getSipSessionId(sipSession)));
9085
9200
 
@@ -9090,17 +9205,17 @@ class WebRTCPhone extends Emitter {
9090
9205
  this.client.on('ended', () => {});
9091
9206
 
9092
9207
  this.client.on(this.client.ON_ERROR, e => {
9093
- logger$7.error('WebRTC error', e);
9208
+ logger$8.error('WebRTC error', e);
9094
9209
  this.eventEmitter.emit(ON_CALL_ERROR, e);
9095
9210
  });
9096
9211
 
9097
9212
  this.client.on(this.client.UNREGISTERED, () => {
9098
- logger$7.info('WebRTC unregistered');
9213
+ logger$8.info('WebRTC unregistered');
9099
9214
  this.eventEmitter.emit(ON_UNREGISTERED);
9100
9215
  });
9101
9216
 
9102
9217
  this.client.on(this.client.REGISTERED, () => {
9103
- logger$7.info('WebRTC registered', {
9218
+ logger$8.info('WebRTC registered', {
9104
9219
  shouldSendReinvite: this.shouldSendReinvite,
9105
9220
  state: this.currentSipSession ? this.currentSipSession.state : null,
9106
9221
  currentSipSession: !!this.currentSipSession,
@@ -9116,19 +9231,19 @@ class WebRTCPhone extends Emitter {
9116
9231
  try {
9117
9232
  this.sendReinvite(this.currentCallSession);
9118
9233
  } catch (e) {
9119
- logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
9234
+ logger$8.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
9120
9235
  }
9121
9236
  }
9122
9237
  });
9123
9238
 
9124
9239
  this.client.on(this.client.CONNECTED, () => {
9125
- logger$7.info('WebRTC client connected');
9240
+ logger$8.info('WebRTC client connected');
9126
9241
 
9127
9242
  this.stopHeartbeat();
9128
9243
  });
9129
9244
 
9130
9245
  this.client.on(this.client.DISCONNECTED, () => {
9131
- logger$7.info('WebRTC client disconnected');
9246
+ logger$8.info('WebRTC client disconnected');
9132
9247
 
9133
9248
  this.eventEmitter.emit(ON_UNREGISTERED);
9134
9249
 
@@ -9360,7 +9475,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
9360
9475
 
9361
9476
  //
9362
9477
 
9363
- const logger$6 = IssueReporter$1.loggerFor('simple-phone');
9478
+ const logger$7 = IssueReporter$1.loggerFor('simple-phone');
9364
9479
  const sipLogger = IssueReporter$1.loggerFor('sip.js');
9365
9480
  const protocolLogger = IssueReporter$1.loggerFor('sip');
9366
9481
 
@@ -9467,7 +9582,7 @@ class Phone extends Emitter {
9467
9582
  async disconnect() {
9468
9583
  if (this.phone) {
9469
9584
  if (this.phone.hasAnActiveCall()) {
9470
- logger$6.info('hangup call on disconnect');
9585
+ logger$7.info('hangup call on disconnect');
9471
9586
  // $FlowFixMe
9472
9587
  await this.phone.hangup();
9473
9588
  }
@@ -9490,13 +9605,13 @@ class Phone extends Emitter {
9490
9605
  }
9491
9606
 
9492
9607
  async hangup(callSession ) {
9493
- logger$6.info('hangup via simple phone', { callId: callSession.getId() });
9608
+ logger$7.info('hangup via simple phone', { callId: callSession.getId() });
9494
9609
 
9495
9610
  return this.phone && this.phone.hangup(callSession);
9496
9611
  }
9497
9612
 
9498
9613
  async accept(callSession , cameraEnabled ) {
9499
- logger$6.info('accept via simple phone', { callId: callSession.getId(), cameraEnabled });
9614
+ logger$7.info('accept via simple phone', { callId: callSession.getId(), cameraEnabled });
9500
9615
 
9501
9616
  return this.phone && this.phone.accept(callSession, cameraEnabled);
9502
9617
  }
@@ -9516,13 +9631,18 @@ class Phone extends Emitter {
9516
9631
  return adHocConference.start();
9517
9632
  }
9518
9633
 
9519
- mute(callSession ) {
9520
- this.muteViaAPI(callSession);
9634
+ mute(callSession , withApi = true) {
9635
+ if (withApi) {
9636
+ this.muteViaAPI(callSession);
9637
+ }
9638
+
9521
9639
  return this.phone && this.phone.mute(callSession);
9522
9640
  }
9523
9641
 
9524
- unmute(callSession ) {
9525
- this.unmuteViaAPI(callSession);
9642
+ unmute(callSession , withApi = true) {
9643
+ if (withApi) {
9644
+ this.unmuteViaAPI(callSession);
9645
+ }
9526
9646
 
9527
9647
  return this.phone && this.phone.unmute(callSession);
9528
9648
  }
@@ -9530,7 +9650,7 @@ class Phone extends Emitter {
9530
9650
  muteViaAPI(callSession ) {
9531
9651
  if (callSession && callSession.callId) {
9532
9652
  Wazo.getApiClient().calld.mute(callSession.callId).catch(e => {
9533
- logger$6.error('Mute via API, error', e);
9653
+ logger$7.error('Mute via API, error', e);
9534
9654
  });
9535
9655
  }
9536
9656
  }
@@ -9538,7 +9658,7 @@ class Phone extends Emitter {
9538
9658
  unmuteViaAPI(callSession ) {
9539
9659
  if (callSession && callSession.callId) {
9540
9660
  Wazo.getApiClient().calld.unmute(callSession.callId).catch(e => {
9541
- logger$6.error('Unmute via API, error', e);
9661
+ logger$7.error('Unmute via API, error', e);
9542
9662
  });
9543
9663
  }
9544
9664
  }
@@ -9628,9 +9748,13 @@ class Phone extends Emitter {
9628
9748
  return this.phone && this.phone.hasLocalVideo(callSession);
9629
9749
  }
9630
9750
 
9751
+ hasALocalVideoTrack(callSession ) {
9752
+ return this.phone && this.phone.hasALocalVideoTrack(callSession);
9753
+ }
9754
+
9631
9755
  // @Deprecated
9632
9756
  getLocalMediaStream(callSession ) {
9633
- logger$6.warn('Phone.getLocalMediaStream is deprecated, use Phone.getLocalStream instead');
9757
+ logger$7.warn('Phone.getLocalMediaStream is deprecated, use Phone.getLocalStream instead');
9634
9758
 
9635
9759
  return this.phone && this.phone.getLocalStream(callSession);
9636
9760
  }
@@ -9649,20 +9773,20 @@ class Phone extends Emitter {
9649
9773
 
9650
9774
  // @Deprecated
9651
9775
  getRemoteStreamForCall(callSession ) {
9652
- logger$6.warn('Phone.getRemoteStreamForCall is deprecated, use Phone.getRemoteStream instead');
9776
+ logger$7.warn('Phone.getRemoteStreamForCall is deprecated, use Phone.getRemoteStream instead');
9653
9777
  return this.getRemoteStream(callSession);
9654
9778
  }
9655
9779
 
9656
9780
  // Returns remote streams directly from the peerConnection
9657
9781
  // @Deprecated
9658
9782
  getRemoteStreamsForCall(callSession ) {
9659
- logger$6.warn('Phone.getRemoteStreamsForCall is deprecated, use Phone.getLocalStream instead');
9783
+ logger$7.warn('Phone.getRemoteStreamsForCall is deprecated, use Phone.getLocalStream instead');
9660
9784
  return this.getLocalStream(callSession);
9661
9785
  }
9662
9786
 
9663
9787
  // @Deprecated
9664
9788
  getRemoteVideoStreamForCall(callSession ) {
9665
- logger$6.warn('Phone.getRemoteVideoStreamForCall is deprecated, use Phone.getRemoteVideoStream instead');
9789
+ logger$7.warn('Phone.getRemoteVideoStreamForCall is deprecated, use Phone.getRemoteVideoStream instead');
9666
9790
 
9667
9791
  return this.getRemoteVideoStream(callSession);
9668
9792
  }
@@ -9792,6 +9916,8 @@ const CONFERENCE_USER_PARTICIPANT_JOINED = 'conference_user_participant_joined';
9792
9916
  const CONFERENCE_USER_PARTICIPANT_LEFT = 'conference_user_participant_left';
9793
9917
  const CONFERENCE_USER_PARTICIPANT_TALK_STARTED = 'conference_user_participant_talk_started';
9794
9918
  const CONFERENCE_USER_PARTICIPANT_TALK_STOPPED = 'conference_user_participant_talk_stopped';
9919
+ const MEETING_USER_PARTICIPANT_JOINED = 'meeting_user_participant_joined';
9920
+ const MEETING_USER_PARTICIPANT_LEFT = 'meeting_user_participant_left';
9795
9921
  const SWITCHBOARD_QUEUED_CALLS_UPDATED = 'switchboard_queued_calls_updated';
9796
9922
  const SWITCHBOARD_QUEUED_CALL_ANSWERED = 'switchboard_queued_call_answered';
9797
9923
  const SWITCHBOARD_HELD_CALLS_UPDATED = 'switchboard_held_calls_updated';
@@ -9833,7 +9959,7 @@ const BLACKLIST_EVENTS = [
9833
9959
  ];
9834
9960
 
9835
9961
  const HEARTBEAT_ENGINE_VERSION = '20.09';
9836
- const logger$5 = IssueReporter$1.loggerFor('wazo-ws');
9962
+ const logger$6 = IssueReporter$1.loggerFor('wazo-ws');
9837
9963
  const messageLogger = IssueReporter$1.loggerFor('wazo-ws-message');
9838
9964
 
9839
9965
  class WebSocketClient extends Emitter {
@@ -9882,19 +10008,19 @@ class WebSocketClient extends Emitter {
9882
10008
  }
9883
10009
 
9884
10010
  connect() {
9885
- logger$5.info('connect method started', { host: this.host, token: this.token });
10011
+ logger$6.info('connect method started', { host: this.host, token: this.token });
9886
10012
  this.socket = new ReconnectingWebSocket__default['default'](this._getUrl.bind(this), [], this.options);
9887
10013
  if (this.options.binaryType) {
9888
10014
  this.socket.binaryType = this.options.binaryType;
9889
10015
  }
9890
10016
 
9891
10017
  this.socket.onopen = () => {
9892
- logger$5.info('on Wazo WS open', { method: 'connect', host: this.host });
10018
+ logger$6.info('on Wazo WS open', { method: 'connect', host: this.host });
9893
10019
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_OPEN);
9894
10020
  };
9895
10021
 
9896
10022
  this.socket.onerror = event => {
9897
- logger$5.error('on Wazo WS error', event.target);
10023
+ logger$6.error('on Wazo WS error', event.target);
9898
10024
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_ERROR, event);
9899
10025
  };
9900
10026
 
@@ -9924,7 +10050,7 @@ class WebSocketClient extends Emitter {
9924
10050
 
9925
10051
  this.socket.onclose = event => {
9926
10052
  // Can't be converted to JSON (circular structure)
9927
- logger$5.info('on Wazo WS close', {
10053
+ logger$6.info('on Wazo WS close', {
9928
10054
  reason: event.reason,
9929
10055
  code: event.code,
9930
10056
  readyState: event.target.readyState,
@@ -9942,12 +10068,12 @@ class WebSocketClient extends Emitter {
9942
10068
  };
9943
10069
 
9944
10070
  this.socket.onerror = event => {
9945
- logger$5.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
10071
+ logger$6.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
9946
10072
  };
9947
10073
  }
9948
10074
 
9949
10075
  close(force = false) {
9950
- logger$5.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
10076
+ logger$6.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
9951
10077
 
9952
10078
  if (!this.socket) {
9953
10079
  return;
@@ -9965,7 +10091,7 @@ class WebSocketClient extends Emitter {
9965
10091
 
9966
10092
  updateToken(token ) {
9967
10093
  this.token = token;
9968
- logger$5.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
10094
+ logger$6.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
9969
10095
 
9970
10096
  if (this.socket) {
9971
10097
  // If still connected, send the token to the WS
@@ -9983,7 +10109,7 @@ class WebSocketClient extends Emitter {
9983
10109
  }
9984
10110
 
9985
10111
  startHeartbeat() {
9986
- logger$5.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
10112
+ logger$6.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
9987
10113
 
9988
10114
  if (!this.socket) {
9989
10115
  this.heartbeat.stop();
@@ -9997,7 +10123,7 @@ class WebSocketClient extends Emitter {
9997
10123
  }
9998
10124
 
9999
10125
  stopHeartbeat() {
10000
- logger$5.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
10126
+ logger$6.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
10001
10127
 
10002
10128
  this.heartbeat.stop();
10003
10129
  }
@@ -10027,7 +10153,7 @@ class WebSocketClient extends Emitter {
10027
10153
  }
10028
10154
 
10029
10155
  reconnect(reason ) {
10030
- logger$5.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
10156
+ logger$6.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
10031
10157
  if (!this.socket) {
10032
10158
  return;
10033
10159
  }
@@ -10083,7 +10209,7 @@ class WebSocketClient extends Emitter {
10083
10209
  this.close();
10084
10210
  }
10085
10211
  const url = `wss://${this.host || ''}/api/websocketd/?token=${this.token || ''}&version=${this.version}`;
10086
- logger$5.log('Wazo WS url computed to reconnect', { url });
10212
+ logger$6.log('Wazo WS url computed to reconnect', { url });
10087
10213
 
10088
10214
  return url;
10089
10215
  }
@@ -10091,12 +10217,12 @@ class WebSocketClient extends Emitter {
10091
10217
  _onHeartbeat(message ) {
10092
10218
  if (message.payload === 'pong') {
10093
10219
  this.heartbeat.onHeartbeat();
10094
- logger$5.log('on heartbeat received from Wazo WS');
10220
+ logger$6.log('on heartbeat received from Wazo WS');
10095
10221
  }
10096
10222
  }
10097
10223
 
10098
10224
  async _onHeartbeatTimeout() {
10099
- logger$5.log('heartbeat timed out', { host: this.host, token: this.token });
10225
+ logger$6.log('heartbeat timed out', { host: this.host, token: this.token });
10100
10226
 
10101
10227
  this.close();
10102
10228
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_CLOSE, new Error('Websocket ping failure.'));
@@ -10138,6 +10264,8 @@ WebSocketClient.eventLists = [
10138
10264
  CHATD_USER_ROOM_CREATED,
10139
10265
  CONFERENCE_USER_PARTICIPANT_JOINED,
10140
10266
  CONFERENCE_USER_PARTICIPANT_LEFT,
10267
+ MEETING_USER_PARTICIPANT_JOINED,
10268
+ MEETING_USER_PARTICIPANT_LEFT,
10141
10269
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
10142
10270
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
10143
10271
  SWITCHBOARD_QUEUED_CALLS_UPDATED,
@@ -10208,6 +10336,8 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
10208
10336
  CONFERENCE_USER_PARTICIPANT_LEFT: CONFERENCE_USER_PARTICIPANT_LEFT,
10209
10337
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED: CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
10210
10338
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED: CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
10339
+ MEETING_USER_PARTICIPANT_JOINED: MEETING_USER_PARTICIPANT_JOINED,
10340
+ MEETING_USER_PARTICIPANT_LEFT: MEETING_USER_PARTICIPANT_LEFT,
10211
10341
  SWITCHBOARD_QUEUED_CALLS_UPDATED: SWITCHBOARD_QUEUED_CALLS_UPDATED,
10212
10342
  SWITCHBOARD_QUEUED_CALL_ANSWERED: SWITCHBOARD_QUEUED_CALL_ANSWERED,
10213
10343
  SWITCHBOARD_HELD_CALLS_UPDATED: SWITCHBOARD_HELD_CALLS_UPDATED,
@@ -10249,7 +10379,7 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
10249
10379
  const { SOCKET_EVENTS, ...OTHER_EVENTS } = WebSocketClient$1;
10250
10380
  const ALL_EVENTS = [...Object.values(SOCKET_EVENTS), ...Object.values(OTHER_EVENTS)];
10251
10381
 
10252
- const logger$4 = IssueReporter$1.loggerFor('simple-ws-client');
10382
+ const logger$5 = IssueReporter$1.loggerFor('simple-ws-client');
10253
10383
 
10254
10384
  class Websocket extends Emitter {
10255
10385
 
@@ -10273,7 +10403,7 @@ class Websocket extends Emitter {
10273
10403
  }
10274
10404
 
10275
10405
  open(host , session ) {
10276
- logger$4.info('open simple WebSocket', { host, token: session.token });
10406
+ logger$5.info('open simple WebSocket', { host, token: session.token });
10277
10407
  this.ws = new WebSocketClient(
10278
10408
  {
10279
10409
  host,
@@ -10301,7 +10431,7 @@ class Websocket extends Emitter {
10301
10431
  }
10302
10432
 
10303
10433
  updateToken(token ) {
10304
- logger$4.info('update token via simple Websocket', { token, ws: !!this.ws });
10434
+ logger$5.info('update token via simple Websocket', { token, ws: !!this.ws });
10305
10435
 
10306
10436
  if (!this.ws) {
10307
10437
  return;
@@ -10329,7 +10459,7 @@ var Websocket$1 = global.wazoWebsocketInstance;
10329
10459
 
10330
10460
  //
10331
10461
 
10332
- const logger$3 = IssueReporter$1.loggerFor('room');
10462
+ const logger$4 = IssueReporter$1.loggerFor('room');
10333
10463
 
10334
10464
  class Participant extends Emitter {
10335
10465
 
@@ -10363,6 +10493,7 @@ class Participant extends Emitter {
10363
10493
 
10364
10494
 
10365
10495
  /**
10496
+ * @param room Room The room where the participant is
10366
10497
  * @param rawParticipant string Participant sent via the Wazo WS
10367
10498
  * @param extra Object extra status of the participant
10368
10499
  */
@@ -10450,7 +10581,7 @@ class Participant extends Emitter {
10450
10581
  }
10451
10582
 
10452
10583
  onTalking(isTalking ) {
10453
- logger$3.info('on participant talking', { name: this.name, isTalking, callId: this.callId });
10584
+ logger$4.info('on participant talking', { name: this.name, isTalking, callId: this.callId });
10454
10585
  this.isTalking = isTalking;
10455
10586
  // you may notice we're not broadcasting: since all participants are getting this info
10456
10587
  // directly from asterisk, there's no need to do so
@@ -10553,7 +10684,7 @@ class Participant extends Emitter {
10553
10684
  }
10554
10685
 
10555
10686
  updateStatus(status , broadcast = true) {
10556
- logger$3.info('updating participant status', { name: this.name, status });
10687
+ logger$4.info('updating participant status', { name: this.name, status });
10557
10688
 
10558
10689
  if (typeof status.audioMuted !== 'undefined' && status.audioMuted !== this.audioMuted) {
10559
10690
  if (status.audioMuted) {
@@ -10590,13 +10721,18 @@ class Participant extends Emitter {
10590
10721
  // Poor man's object comparison
10591
10722
  if (typeof status.extra !== 'undefined' && JSON.stringify(this.extra) !== JSON.stringify(status.extra)) {
10592
10723
  this.extra = { ...this.extra, ...status.extra };
10724
+
10725
+ if (this.extra.contact && !(this.extra.contact instanceof Contact)) {
10726
+ this.extra.contact = new Contact(this.extra.contact);
10727
+ }
10728
+
10593
10729
  this.triggerUpdate(this.ON_EXTRA_CHANGE, broadcast);
10594
10730
  }
10595
10731
  }
10596
10732
 
10597
10733
  broadcastStatus(inboundStatus = null) {
10598
10734
  const status = inboundStatus || this.getStatus();
10599
- logger$3.info('broadcasting participant status', { callId: this.callId, status });
10735
+ logger$4.info('broadcasting participant status', { callId: this.callId, status });
10600
10736
 
10601
10737
  this.room.sendSignal({
10602
10738
  type: SIGNAL_TYPE_PARTICIPANT_UPDATE,
@@ -10617,18 +10753,24 @@ class RemoteParticipant extends Participant {
10617
10753
  }
10618
10754
  }
10619
10755
 
10620
- /* global document */
10756
+ //
10757
+
10758
+ class LocalParticipant extends Participant {
10759
+ }
10760
+
10761
+ //
10621
10762
 
10622
10763
  const SIGNAL_TYPE_PARTICIPANT_UPDATE = 'signal/PARTICIPANT_UPDATE';
10623
10764
  const SIGNAL_TYPE_PARTICIPANT_REQUEST = 'signal/PARTICIPANT_REQUEST';
10624
10765
 
10625
- const logger$2 = IssueReporter$1.loggerFor('sdk-room');
10766
+ const logger$3 = IssueReporter$1.loggerFor('sdk-room');
10626
10767
 
10627
10768
  class Room$1 extends Emitter {
10628
10769
 
10629
10770
 
10630
10771
 
10631
10772
 
10773
+
10632
10774
 
10633
10775
 
10634
10776
 
@@ -10650,6 +10792,8 @@ class Room$1 extends Emitter {
10650
10792
 
10651
10793
 
10652
10794
 
10795
+
10796
+
10653
10797
 
10654
10798
 
10655
10799
 
@@ -10667,6 +10811,7 @@ class Room$1 extends Emitter {
10667
10811
  * @param extension string
10668
10812
  * @param sourceId number
10669
10813
  * @param callId string
10814
+ * @param meetingUuid string
10670
10815
  * @param extra Object
10671
10816
  */
10672
10817
  constructor(
@@ -10674,15 +10819,17 @@ class Room$1 extends Emitter {
10674
10819
  extension ,
10675
10820
  sourceId ,
10676
10821
  callId ,
10822
+ meetingUuid ,
10677
10823
  extra = {},
10678
10824
  ) {
10679
10825
  super();
10680
- logger$2.info('room initialized', { callId, extension, sourceId });
10826
+ logger$3.info('room initialized', { callId, extension, sourceId, meetingUuid });
10681
10827
 
10682
10828
  // Represents the room callSession
10683
10829
  this.callSession = callSession;
10684
10830
  this.extension = extension;
10685
10831
  this.sourceId = sourceId;
10832
+ this.meetingUuid = meetingUuid;
10686
10833
  this.callId = callId;
10687
10834
  this.participants = [];
10688
10835
  this.connected = false;
@@ -10702,6 +10849,8 @@ class Room$1 extends Emitter {
10702
10849
  // Sugar syntax for `room.EVENT_NAME`
10703
10850
  this.CONFERENCE_USER_PARTICIPANT_JOINED = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_JOINED;
10704
10851
  this.CONFERENCE_USER_PARTICIPANT_LEFT = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_LEFT;
10852
+ this.MEETING_USER_PARTICIPANT_JOINED = Wazo.Websocket.MEETING_USER_PARTICIPANT_JOINED;
10853
+ this.MEETING_USER_PARTICIPANT_LEFT = Wazo.Websocket.MEETING_USER_PARTICIPANT_LEFT;
10705
10854
  this.ON_SHARE_SCREEN_ENDED = Wazo.Phone.ON_SHARE_SCREEN_ENDED;
10706
10855
  this.ON_MESSAGE = Wazo.Phone.ON_MESSAGE;
10707
10856
  this.ON_CHAT = Wazo.Phone.ON_CHAT;
@@ -10736,10 +10885,11 @@ class Room$1 extends Emitter {
10736
10885
  * @param audioOnly boolean
10737
10886
  * @param extra Object
10738
10887
  * @param room ?Room
10888
+ * @param meeting ?Meeting
10739
10889
  * @returns {Promise<Room>}
10740
10890
  */
10741
- static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
10742
- logger$2.info('connecting to room', { extension, audioOnly, room: !!room });
10891
+ static async connect({ extension, constraints, audioOnly = false, extra, room, meeting } ) {
10892
+ logger$3.info('connecting to room', { extension, audioOnly, room: !!room });
10743
10893
 
10744
10894
  if (!room) {
10745
10895
  await Wazo.Phone.connect();
@@ -10752,7 +10902,7 @@ class Room$1 extends Emitter {
10752
10902
 
10753
10903
  // Call_created is triggered before call_accepted, so we have to listen for it here.
10754
10904
  Wazo.Websocket.once(Wazo.Websocket.CALL_CREATED, ({ data }) => {
10755
- logger$2.info('room call received via WS', { callId: data.call_id });
10905
+ logger$3.info('room call received via WS', { callId: data.call_id });
10756
10906
  if (room) {
10757
10907
  room.setCallId(data.call_id);
10758
10908
  }
@@ -10773,34 +10923,44 @@ class Room$1 extends Emitter {
10773
10923
  room.setCallId(room.callSession.call.id);
10774
10924
  }
10775
10925
 
10776
- // Fetch conference source
10777
- const sources = await getApiClient().dird.fetchConferenceSource('default');
10778
- // Retrieve conference sources
10779
- const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
10780
- // Retrieve conference
10781
- const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
10926
+ if (!meeting) {
10927
+ // Fetch conference source
10928
+ const sources = await getApiClient().dird.fetchConferenceSource('default');
10929
+ // Retrieve conference sources
10930
+ const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
10931
+ // Retrieve conference
10932
+ const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
10782
10933
 
10783
- logger$2.info('connected to room', {
10784
- sourceId: conference ? conference.sourceId : null,
10785
- name: conference ? conference.name : null,
10786
- });
10934
+ logger$3.info('connected to room', {
10935
+ sourceId: conference ? conference.sourceId : null,
10936
+ name: conference ? conference.name : null,
10937
+ });
10787
10938
 
10788
- if (conference) {
10789
- room.setSourceId(conference.sourceId);
10790
- room.setName(conference.name);
10939
+ if (conference) {
10940
+ room.setSourceId(conference.sourceId);
10941
+ room.setName(conference.name);
10942
+ }
10943
+ } else if (meeting) {
10944
+ logger$3.info('Already connected to meeting', {
10945
+ uuid: meeting.uuid,
10946
+ name: meeting.name,
10947
+ });
10948
+
10949
+ room.setMeetingUuid(meeting.uuid);
10950
+ room.setName(meeting.name);
10791
10951
  }
10792
10952
 
10793
10953
  return room;
10794
10954
  }
10795
10955
 
10796
10956
  static disconnect() {
10797
- logger$2.info('static disconnection to room');
10957
+ logger$3.info('static disconnection to room');
10798
10958
 
10799
10959
  Wazo.Phone.disconnect();
10800
10960
  }
10801
10961
 
10802
10962
  async disconnect() {
10803
- logger$2.info('disconnection to room called');
10963
+ logger$3.info('disconnection to room called');
10804
10964
 
10805
10965
  await Wazo.Phone.hangup(this.callSession);
10806
10966
  this.callSession = null;
@@ -10815,20 +10975,24 @@ class Room$1 extends Emitter {
10815
10975
  Wazo.Phone.phone.off(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
10816
10976
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
10817
10977
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
10818
-
10819
- if (this.roomAudioElement && document.body) {
10820
- document.body.removeChild(this.roomAudioElement);
10821
- }
10978
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
10979
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
10822
10980
  }
10823
10981
 
10824
10982
  setSourceId(sourceId ) {
10825
- logger$2.info('set room source id', { sourceId });
10983
+ logger$3.info('set room source id', { sourceId });
10826
10984
 
10827
10985
  this.sourceId = sourceId;
10828
10986
  }
10829
10987
 
10988
+ setMeetingUuid(meetingUuid ) {
10989
+ logger$3.info('set meeting uuid', { meetingUuid });
10990
+
10991
+ this.meetingUuid = meetingUuid;
10992
+ }
10993
+
10830
10994
  setCallId(callId ) {
10831
- logger$2.info('set room call id', { callId });
10995
+ logger$3.info('set room call id', { callId });
10832
10996
 
10833
10997
  if (callId) {
10834
10998
  this.callId = callId;
@@ -10836,7 +11000,7 @@ class Room$1 extends Emitter {
10836
11000
  }
10837
11001
 
10838
11002
  setName(name ) {
10839
- logger$2.info('set room name', { name });
11003
+ logger$3.info('set room name', { name });
10840
11004
 
10841
11005
  this.name = name;
10842
11006
  }
@@ -10855,7 +11019,7 @@ class Room$1 extends Emitter {
10855
11019
  }
10856
11020
 
10857
11021
  async startScreenSharing(constraints ) {
10858
- logger$2.info('start room screen sharing', { constraints });
11022
+ logger$3.info('start room screen sharing', { constraints });
10859
11023
 
10860
11024
  const screensharingStream = await Wazo.Phone.startScreenSharing(constraints, this.callSession);
10861
11025
  if (!screensharingStream) {
@@ -10868,18 +11032,26 @@ class Room$1 extends Emitter {
10868
11032
  return screensharingStream;
10869
11033
  }
10870
11034
 
10871
- stopScreenSharing(restoreLocalStream = true) {
10872
- logger$2.info('stop room screen sharing');
11035
+ async stopScreenSharing(restoreLocalStream = true) {
11036
+ logger$3.info('stop room screen sharing');
10873
11037
 
10874
- Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
11038
+ const reinvited = await Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
10875
11039
 
10876
11040
  if (this.localParticipant) {
10877
11041
  this.localParticipant.onStopScreensharing();
10878
11042
  }
11043
+
11044
+ if (!reinvited && this.localParticipant) {
11045
+ // When we had video and we made a screenshare we don't reinvite when stopping the screensahre
11046
+ // So not REINVITE even is fired, we have to restore the video stream manually
11047
+ const localVideoStream = Wazo.Phone.getLocalVideoStream(this.callSession);
11048
+ // $FlowFixMe
11049
+ this._associateStreamTo(localVideoStream, this.localParticipant);
11050
+ }
10879
11051
  }
10880
11052
 
10881
11053
  turnCameraOff() {
10882
- logger$2.info('turn room camera off');
11054
+ logger$3.info('turn room camera off');
10883
11055
 
10884
11056
  Wazo.Phone.turnCameraOff(this.callSession);
10885
11057
 
@@ -10889,7 +11061,7 @@ class Room$1 extends Emitter {
10889
11061
  }
10890
11062
 
10891
11063
  turnCameraOn() {
10892
- logger$2.info('turn room camera on');
11064
+ logger$3.info('turn room camera on');
10893
11065
 
10894
11066
  Wazo.Phone.turnCameraOn(this.callSession);
10895
11067
 
@@ -10899,7 +11071,7 @@ class Room$1 extends Emitter {
10899
11071
  }
10900
11072
 
10901
11073
  mute() {
10902
- logger$2.info('mute room');
11074
+ logger$3.info('mute room');
10903
11075
 
10904
11076
  Wazo.Phone.mute(this.callSession);
10905
11077
 
@@ -10907,7 +11079,7 @@ class Room$1 extends Emitter {
10907
11079
  }
10908
11080
 
10909
11081
  unmute() {
10910
- logger$2.info('unmute room');
11082
+ logger$3.info('unmute room');
10911
11083
 
10912
11084
  Wazo.Phone.unmute(this.callSession);
10913
11085
 
@@ -10927,7 +11099,7 @@ class Room$1 extends Emitter {
10927
11099
  }
10928
11100
 
10929
11101
  hold() {
10930
- logger$2.info('hold room');
11102
+ logger$3.info('hold room');
10931
11103
 
10932
11104
  Wazo.Phone.hold(this.callSession, true);
10933
11105
 
@@ -10937,7 +11109,7 @@ class Room$1 extends Emitter {
10937
11109
  }
10938
11110
 
10939
11111
  resume() {
10940
- logger$2.info('resume room');
11112
+ logger$3.info('resume room');
10941
11113
 
10942
11114
  Wazo.Phone.resume(this.callSession, true);
10943
11115
 
@@ -10947,13 +11119,13 @@ class Room$1 extends Emitter {
10947
11119
  }
10948
11120
 
10949
11121
  sendDTMF(tone ) {
10950
- logger$2.info('send room DTMF', { tone });
11122
+ logger$3.info('send room DTMF', { tone });
10951
11123
 
10952
11124
  Wazo.Phone.sendDTMF(tone, this.callSession);
10953
11125
  }
10954
11126
 
10955
11127
  async sendReinvite(newConstraints = null) {
10956
- logger$2.info('send room reinvite', { callId: this.callSession ? this.callSession.getId() : null, newConstraints });
11128
+ logger$3.info('send room reinvite', { callId: this.callSession ? this.callSession.getId() : null, newConstraints });
10957
11129
  const wasScreensharing = this.localParticipant && this.localParticipant.screensharing;
10958
11130
 
10959
11131
  Wazo.Phone.on(Wazo.Phone.ON_SHARE_SCREEN_STARTED, () => {
@@ -10978,6 +11150,22 @@ class Room$1 extends Emitter {
10978
11150
  return response;
10979
11151
  }
10980
11152
 
11153
+ hasALocalVideoTrack() {
11154
+ return Wazo.Phone.hasALocalVideoTrack(this.callSession);
11155
+ }
11156
+
11157
+ getLocalStream() {
11158
+ return Wazo.Phone.getLocalStream(this.callSession);
11159
+ }
11160
+
11161
+ getRemoteStream() {
11162
+ return Wazo.Phone.getRemoteStream(this.callSession);
11163
+ }
11164
+
11165
+ getRemoteVideoStream() {
11166
+ return Wazo.Phone.getRemoteVideoStream(this.callSession);
11167
+ }
11168
+
10981
11169
  _bindEvents() {
10982
11170
  if (!Wazo.Phone.phone || !Wazo.Phone.phone.currentSipSession) {
10983
11171
  return;
@@ -10996,35 +11184,18 @@ class Room$1 extends Emitter {
10996
11184
  Wazo.Phone.phone.on(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
10997
11185
 
10998
11186
  this.on(this.ON_AUDIO_STREAM, stream => {
10999
- logger$2.info('on room audio stream');
11187
+ logger$3.info('on room audio stream');
11000
11188
 
11001
11189
  this.audioStream = stream;
11002
- if (document.createElement) {
11003
- // $FlowFixMe
11004
- let roomAudioElement = document.getElementById('audio-room');
11005
- if (!this.roomAudioElement) {
11006
- roomAudioElement = document.createElement('audio');
11007
- // $FlowFixMe
11008
- document.body.appendChild(roomAudioElement);
11009
- }
11010
- if (!roomAudioElement) {
11011
- return;
11012
- }
11013
- this.roomAudioElement = roomAudioElement;
11190
+ if (!this.roomAudioElement) {
11191
+ const sessionId = Wazo.Phone.phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
11192
+ this.roomAudioElement = Wazo.Phone.phone.createAudioElementFor(sessionId);
11014
11193
  this.roomAudioElement.srcObject = stream;
11015
- this.roomAudioElement.autoplay = true;
11016
- this.roomAudioElement.id = 'audio-room';
11017
-
11018
- // $FlowFixMe
11019
- if (this.roomAudioElement.setSinkId) {
11020
- // $FlowFixMe
11021
- this.roomAudioElement.setSinkId(Wazo.Phone.getOutputDevice());
11022
- }
11023
11194
  }
11024
11195
  });
11025
11196
 
11026
11197
  this.on(this.ON_VIDEO_STREAM, (stream, streamId, event, sipSession) => {
11027
- logger$2.info('on room video stream', { streamId });
11198
+ logger$3.info('on room video stream', { streamId });
11028
11199
 
11029
11200
  this._mapMsid(sipSession.body.body);
11030
11201
 
@@ -11039,7 +11210,7 @@ class Room$1 extends Emitter {
11039
11210
  });
11040
11211
 
11041
11212
  this.on(this.ON_REMOVE_STREAM, stream => {
11042
- logger$2.info('on room remove stream');
11213
+ logger$3.info('on room remove stream');
11043
11214
 
11044
11215
  const participant = this.participants.find(someParticipant =>
11045
11216
  someParticipant.streams.find(someStream => someStream && someStream.id === stream.id));
@@ -11094,6 +11265,9 @@ class Room$1 extends Emitter {
11094
11265
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
11095
11266
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
11096
11267
 
11268
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
11269
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
11270
+
11097
11271
  // Phone events
11098
11272
  Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
11099
11273
  Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
@@ -11104,15 +11278,15 @@ class Room$1 extends Emitter {
11104
11278
  Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
11105
11279
  }
11106
11280
 
11107
- _onMessage(message ) {
11281
+ _onMessage(message ) {
11108
11282
  if (message.method !== 'MESSAGE') {
11109
- return;
11283
+ return null;
11110
11284
  }
11111
11285
  let body;
11112
11286
  try {
11113
11287
  body = JSON.parse(message.body);
11114
11288
  } catch (e) {
11115
- return;
11289
+ return null;
11116
11290
  }
11117
11291
 
11118
11292
  switch (body.type) {
@@ -11131,6 +11305,8 @@ class Room$1 extends Emitter {
11131
11305
  }
11132
11306
 
11133
11307
  this.eventEmitter.emit(this.ON_MESSAGE, body);
11308
+
11309
+ return body;
11134
11310
  }
11135
11311
 
11136
11312
  _onChat(content ) {
@@ -11166,7 +11342,7 @@ class Room$1 extends Emitter {
11166
11342
  const requester = this._getParticipantFromCallId(origin.callId);
11167
11343
  if (requester) {
11168
11344
  // @FIXME?: when need to trigger an update on join-in; this is a bit of a hack
11169
- logger$2.info('trigger room requester status', { origin });
11345
+ logger$3.info('trigger room requester status', { origin });
11170
11346
  requester.triggerUpdate('REQUESTER_UPDATE');
11171
11347
  }
11172
11348
  break;
@@ -11195,25 +11371,26 @@ class Room$1 extends Emitter {
11195
11371
  const session = Wazo.Auth.getSession();
11196
11372
  let participants = [];
11197
11373
 
11198
- // @TODO: we could use a better function name here
11199
- const isJoining = part => {
11200
- this.__associateStreams(part);
11201
- // @VALIDATE: no need to publicize ourselves, no?
11202
- if (part instanceof RemoteParticipant) {
11203
- this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, part);
11204
- }
11205
- };
11206
-
11207
11374
  // When we join the room, we can call `getConferenceParticipantsAsUser`, not before.
11208
11375
  if (participant.user_uuid === session.uuid) {
11209
- logger$2.info('room current user joined');
11376
+ logger$3.info('room current user joined');
11210
11377
 
11211
11378
  // Retrieve participants via an API calls
11212
11379
  const conferenceId = this.sourceId || payload.data.conference_id;
11213
- const response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
11214
- logger$2.info('fetching conference participants', { conferenceId });
11380
+ let response;
11381
+ try {
11382
+ if (this.meetingUuid) {
11383
+ logger$3.info('fetching meeting participants', { meetingUuid: this.meetingUuid });
11384
+ response = await getApiClient().calld.getMeetingParticipantsAsUser(this.meetingUuid);
11385
+ } else {
11386
+ logger$3.info('fetching conference participants', { conferenceId });
11387
+ response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
11388
+ }
11389
+ } catch (e) {
11390
+ logger$3.error('room participants fetching, error', e);
11391
+ }
11215
11392
  if (response) {
11216
- logger$2.info('conference participants fetched', { nb: response.items.length });
11393
+ logger$3.info('conference participants fetched', { nb: response.items.length });
11217
11394
  participants = response.items.map(item => {
11218
11395
  const isMe = item.call_id === this.callId;
11219
11396
 
@@ -11226,25 +11403,10 @@ class Room$1 extends Emitter {
11226
11403
 
11227
11404
  const localParticipant = participants.find(someParticipant => someParticipant instanceof Wazo.LocalParticipant);
11228
11405
  if (!this.localParticipant && localParticipant) {
11229
- this.localParticipant = localParticipant;
11230
-
11231
- const localVideoStream = this._getLocalVideoStream();
11232
- if (localVideoStream) {
11233
- this._saveLocalVideoStream(localVideoStream);
11234
- }
11235
-
11236
- this.connected = true;
11237
-
11238
- // we're in the room, now let's request everyone's status
11239
- if (this.localParticipant) {
11240
- this.sendSignal({
11241
- type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
11242
- origin: this.localParticipant.getStatus(),
11243
- });
11244
- }
11406
+ this._onLocalParticipantJoined(localParticipant);
11245
11407
  }
11246
11408
 
11247
- participants.forEach(someParticipant => isJoining(someParticipant));
11409
+ participants.forEach(someParticipant => this._isParticipantJoining(someParticipant));
11248
11410
  this.eventEmitter.emit(this.ON_JOINED, localParticipant, participants);
11249
11411
  }
11250
11412
 
@@ -11255,16 +11417,45 @@ class Room$1 extends Emitter {
11255
11417
  ? new Wazo.RemoteParticipant(this, participant)
11256
11418
  : null;
11257
11419
 
11258
- logger$2.info('other room user joined', { callId: participant.call_id, remoteParticipant: !!remoteParticipant });
11420
+ logger$3.info('other room user joined', { callId: participant.call_id, remoteParticipant: !!remoteParticipant });
11259
11421
 
11260
11422
  if (remoteParticipant) {
11261
11423
  this.participants.push(remoteParticipant);
11262
- isJoining(remoteParticipant);
11424
+ this._isParticipantJoining(remoteParticipant);
11263
11425
  }
11264
11426
 
11265
11427
  return remoteParticipant;
11266
11428
  }
11267
11429
 
11430
+ _onLocalParticipantJoined(localParticipant ) {
11431
+ this.localParticipant = localParticipant;
11432
+
11433
+ const localVideoStream = this._getLocalVideoStream();
11434
+ if (localVideoStream) {
11435
+ this._saveLocalVideoStream(localVideoStream);
11436
+ }
11437
+
11438
+ this.connected = true;
11439
+
11440
+ localParticipant.broadcastStatus();
11441
+
11442
+ // we're in the room, now let's request everyone's status
11443
+ if (this.localParticipant) {
11444
+ this.sendSignal({
11445
+ type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
11446
+ origin: this.localParticipant.getStatus(),
11447
+ });
11448
+ }
11449
+ }
11450
+
11451
+ _isParticipantJoining(participant ) {
11452
+ this.__associateStreams(participant);
11453
+ // @VALIDATE: no need to publicize ourselves, no?
11454
+ if (participant instanceof RemoteParticipant) {
11455
+ this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, participant);
11456
+ }
11457
+ }
11458
+
11268
11459
  _saveLocalVideoStream(stream ) {
11269
11460
  const { localParticipant } = this;
11270
11461
 
@@ -11310,9 +11501,11 @@ class Room$1 extends Emitter {
11310
11501
  _onParticipantTrackUpdate(oldParticipant , update ) {
11311
11502
  const newParticipant = oldParticipant;
11312
11503
 
11313
- const { trackId } = this._callIdStreamIdMap[newParticipant.callId] || {};
11504
+ const { trackId, streamId } = this._callIdStreamIdMap[newParticipant.callId] || {};
11314
11505
  const pc = Wazo.Phone.phone.currentSipSession.sessionDescriptionHandler.peerConnection;
11315
- const stream = pc.getRemoteStreams().find(someStream => someStream.getTracks().some(track => track.id === trackId));
11506
+ // Can't use `getReceivers` here because on FF we make the mapping based on the streamId
11507
+ const stream = pc.getRemoteStreams().find(someStream =>
11508
+ someStream.id === streamId || someStream.getTracks().some(track => track.id === trackId));
11316
11509
 
11317
11510
  if (update === 'downgrade') {
11318
11511
  newParticipant.streams = [];
@@ -11342,15 +11535,42 @@ class Room$1 extends Emitter {
11342
11535
  return;
11343
11536
  }
11344
11537
 
11345
- if (this._unassociatedVideoStreams[trackId]) {
11538
+ const streamId = this._getStreamIdFrTrackId(trackId);
11539
+ const key = this._getUnassociatedMapIdFromTrackIdOrStreamId(trackId, streamId);
11540
+ const stream = this._unassociatedVideoStreams[key];
11541
+
11542
+ if (stream) {
11346
11543
  // Try to associate stream
11347
- this._associateStreamTo(this._unassociatedVideoStreams[trackId], participant);
11544
+ this._associateStreamTo(stream, participant);
11348
11545
 
11349
- delete this._unassociatedVideoStreams[trackId];
11546
+ delete this._unassociatedVideoStreams[key];
11350
11547
  delete this._unassociatedParticipants[participant.callId];
11351
11548
  }
11352
11549
  }
11353
11550
 
11551
+ _getUnassociatedMapIdFromTrackIdOrStreamId(trackId , streamId ) {
11552
+ // Find by trackId
11553
+ if (trackId in this._unassociatedVideoStreams) {
11554
+ return trackId;
11555
+ }
11556
+
11557
+ // Find by streamId
11558
+ if (streamId && streamId in this._unassociatedVideoStreams) {
11559
+ return streamId;
11560
+ }
11561
+
11562
+ // Find in all the streams by streamId (used on FF where we can't map by trackId)
11563
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
11564
+ stream && stream.id === streamId);
11565
+ return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
11566
+ }
11567
+
11568
+ _getStreamIdFrTrackId(trackId ) {
11569
+ const mapping = Object.values(this._callIdStreamIdMap).find((map ) => map.trackId === trackId);
11570
+
11571
+ return mapping ? mapping.streamId : null;
11572
+ }
11573
+
11354
11574
  _associateStreamTo(rawStream , participant ) {
11355
11575
  const stream = new Wazo.Stream(rawStream, participant);
11356
11576
  participant.streams.push(stream);
@@ -11374,7 +11594,141 @@ class Room$1 extends Emitter {
11374
11594
 
11375
11595
  //
11376
11596
 
11377
- class LocalParticipant extends Participant {
11597
+ const logger$2 = IssueReporter$1.loggerFor('sdk-sip-room');
11598
+
11599
+ class SipRoom extends Room$1 {
11600
+
11601
+ static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
11602
+ logger$2.info('connecting to sip room', { extension, audioOnly, room: !!room });
11603
+
11604
+ if (!room) {
11605
+ await Wazo.Phone.connect();
11606
+
11607
+ const withCamera = constraints && !!constraints.video;
11608
+
11609
+ const callSession = await Wazo.Phone.call(extension, withCamera, null, audioOnly, true);
11610
+ // eslint-disable-next-line no-param-reassign
11611
+ room = new SipRoom(callSession, extension, null, null, extra);
11612
+ }
11613
+
11614
+ if (room && room.callSession && room.callSession.call) {
11615
+ room.setCallId(room.callSession.call.id);
11616
+ }
11617
+
11618
+ logger$2.info('connected to room', {
11619
+ extension: room.extension,
11620
+ });
11621
+
11622
+ return room;
11623
+ }
11624
+
11625
+ mute() {
11626
+ logger$2.info('mute sip room');
11627
+
11628
+ Wazo.Phone.mute(this.callSession, false);
11629
+
11630
+ this.sendMuteStatus();
11631
+ }
11632
+
11633
+ unmute() {
11634
+ logger$2.info('unmute sip room');
11635
+
11636
+ Wazo.Phone.unmute(this.callSession, false);
11637
+
11638
+ this.sendUnMuteStatus();
11639
+ }
11640
+
11641
+ getLocalGuestName() {
11642
+ return Wazo.Phone.phone.client.userAgent.options.displayName;
11643
+ }
11644
+
11645
+ // Overridden to not listen to websocket messages
11646
+ _transferEvents() {
11647
+ // Phone events
11648
+ Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
11649
+ Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
11650
+ Wazo.Phone.on(this.ON_SIGNAL, this._boundOnSignal);
11651
+ Wazo.Phone.on(this.ON_VIDEO_INPUT_CHANGE, this._boundSaveLocalVideoStream);
11652
+
11653
+ [this.ON_AUDIO_STREAM, this.ON_VIDEO_STREAM, this.ON_REMOVE_STREAM].forEach(event =>
11654
+ Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
11655
+ }
11656
+
11657
+ _onMessage(message ) {
11658
+ // eslint-disable-next-line no-underscore-dangle
11659
+ const body = super._onMessage(message);
11660
+ if (!body) {
11661
+ return;
11662
+ }
11663
+
11664
+ const getChannel = () => body.channels[0];
11665
+
11666
+ switch (body.type) {
11667
+ case 'ConfbridgeWelcome':
11668
+ body.channels.forEach(channel => {
11669
+ this._onParticipantJoined(channel);
11670
+ });
11671
+
11672
+ break;
11673
+ case 'ConfbridgeJoin': {
11674
+ const channel = getChannel();
11675
+ this._onParticipantJoined(channel);
11676
+ break;
11677
+ }
11678
+ case 'ConfbridgeLeave': {
11679
+ const channel = getChannel();
11680
+ this._onParticipantLeft({
11681
+ data: {
11682
+ call_id: channel.id,
11683
+ },
11684
+ });
11685
+ break;
11686
+ }
11687
+ }
11688
+ }
11689
+
11690
+ async _onParticipantJoined(channel ) {
11691
+ const isLocal = channel.channelvars.WAZO_SIP_CALL_ID === this._getCurrentSipCallIs();
11692
+ const callId = channel.id;
11693
+ const ParticipantClass = isLocal ? Wazo.LocalParticipant : Wazo.RemoteParticipant;
11694
+ const name = channel.caller ? channel.caller.name : null;
11695
+ const extra = isLocal ? { guestName: this.getLocalGuestName() } : {};
11696
+ const participant = new ParticipantClass(this, {
11697
+ caller_id_name: name,
11698
+ call_id: callId,
11699
+ }, extra);
11700
+
11701
+ const participantIdx = this.participants.findIndex(other => other.callId === participant.callId);
11702
+ if (participantIdx !== -1 && name) {
11703
+ this.participants[participantIdx].name = name;
11704
+ return;
11705
+ }
11706
+
11707
+ if (isLocal) {
11708
+ // Should be updated by the Wazo WS but we don't have it for now
11709
+ if (this.callSession) {
11710
+ this.callSession.ringing = false;
11711
+ }
11712
+
11713
+ this._onLocalParticipantJoined(participant);
11714
+
11715
+ // Give some time for the stream to be updated
11716
+ setTimeout(() => {
11717
+ this.eventEmitter.emit(this.ON_JOINED, participant, this.participants);
11718
+ }, 1000);
11719
+ }
11720
+
11721
+ this.participants.push(participant);
11722
+
11723
+ this._isParticipantJoining(participant);
11724
+
11725
+ return participant;
11726
+ }
11727
+
11728
+ _getCurrentSipCallIs() {
11729
+ return Wazo.Phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
11730
+ }
11731
+
11378
11732
  }
11379
11733
 
11380
11734
  /* global document */
@@ -11427,9 +11781,7 @@ class Stream {
11427
11781
  return false;
11428
11782
  }
11429
11783
 
11430
- // With canvas track (used to fake upgrade in conference), we don't have a width
11431
- return this.htmlStream.getTracks().find(track => track.kind === 'video'
11432
- && track.readyState !== 'ended' && 'width' in track.getSettings());
11784
+ return this.htmlStream.getTracks().some(track => track.kind === 'video' && track.readyState !== 'ended');
11433
11785
  }
11434
11786
 
11435
11787
  get id() {
@@ -12330,6 +12682,7 @@ const Wazo = {
12330
12682
  Phone: Phone$1,
12331
12683
  Websocket: Websocket$1,
12332
12684
  Room: Room$1,
12685
+ SipRoom,
12333
12686
  RemoteParticipant,
12334
12687
  LocalParticipant,
12335
12688
  Stream,
@@ -12366,6 +12719,7 @@ const Wazo = {
12366
12719
  IndirectTransfer,
12367
12720
  SwitchboardCall,
12368
12721
  WebRTCPhone,
12722
+ Meeting,
12369
12723
  },
12370
12724
 
12371
12725
  // Api