@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
@@ -2493,6 +2493,65 @@ class ExternalApp {
2493
2493
  }
2494
2494
  }
2495
2495
 
2496
+ //
2497
+
2498
+
2499
+
2500
+
2501
+
2502
+
2503
+
2504
+
2505
+
2506
+
2507
+
2508
+ class Meeting {
2509
+
2510
+
2511
+
2512
+
2513
+
2514
+
2515
+
2516
+
2517
+
2518
+
2519
+ static parse(plain ) {
2520
+ return new Meeting({
2521
+ guestSipAuthorization: plain.guest_sip_authorization,
2522
+ hostname: plain.hostname,
2523
+ name: plain.name,
2524
+ ownerUuids: plain.owner_uuids,
2525
+ port: plain.port,
2526
+ uuid: plain.uuid,
2527
+ number: plain.number,
2528
+ });
2529
+ }
2530
+
2531
+ static newFrom(meeting ) {
2532
+ return newFrom(meeting, Meeting);
2533
+ }
2534
+
2535
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
2536
+ this.guestSipAuthorization = guestSipAuthorization;
2537
+ this.hostname = hostname;
2538
+ this.name = name;
2539
+ this.ownerUuids = ownerUuids;
2540
+ this.port = port;
2541
+ this.uuid = uuid;
2542
+ this.number = number;
2543
+
2544
+ // Useful to compare instead of instanceof with minified code
2545
+ this.type = 'Meeting';
2546
+ }
2547
+
2548
+ getGuestSipCredentials() {
2549
+ // eslint-disable-next-line no-undef
2550
+ const [username, secret] = atob(this.guestSipAuthorization).split(':');
2551
+ return { username, secret };
2552
+ }
2553
+ }
2554
+
2496
2555
  /* */
2497
2556
 
2498
2557
  var confdMethods = (client , baseUrl ) => ({
@@ -2557,6 +2616,18 @@ var confdMethods = (client , baseUrl ) => ({
2557
2616
  return null;
2558
2617
  }
2559
2618
  },
2619
+
2620
+ createMyMeeting: (name ) =>
2621
+ client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
2622
+
2623
+ deleteMyMeeting: (meetingUuid ) =>
2624
+ client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
2625
+
2626
+ getMeeting: (meetingUuid ) =>
2627
+ client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
2628
+
2629
+ guestGetMeeting: (meetingUuid ) =>
2630
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
2560
2631
  });
2561
2632
 
2562
2633
  //
@@ -3141,7 +3212,11 @@ class CallLog {
3141
3212
  answered: plain.answered,
3142
3213
  callDirection: plain.call_direction,
3143
3214
  destination: {
3144
- extension: plain.requested_extension || plain.destination_extension,
3215
+ // @TEMP: Temporarily assuming empty numbers are meetings
3216
+ // which is admittedly a very dangerous assumption. Did i mention it was temporary?
3217
+ extension: plain.requested_extension
3218
+ || plain.destination_extension
3219
+ || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3145
3220
  name: plain.requested_name || plain.destination_name || '',
3146
3221
  },
3147
3222
  source: {
@@ -3157,27 +3232,11 @@ class CallLog {
3157
3232
  }
3158
3233
 
3159
3234
  static parseNew(plain , session ) {
3160
- return new CallLog({
3161
- answer: plain.answer ? moment(plain.answer).toDate() : null,
3162
- answered: plain.answered,
3163
- callDirection: plain.call_direction,
3164
- destination: {
3165
- extension: plain.requested_extension || plain.destination_extension,
3166
- name: plain.requested_name || plain.destination_name || '',
3167
- },
3168
- source: {
3169
- extension: plain.source_extension,
3170
- name: plain.source_name,
3171
- },
3172
- id: plain.id,
3173
- duration: (plain.duration || 0) * 1000, // duration is in seconds
3174
- start: moment(plain.start).toDate(),
3175
- end: plain.end ? moment(plain.end).toDate() : null,
3176
- recordings: Recording.parseMany(plain.recordings),
3177
- // @TODO: FIXME add verification declined vs missed call
3178
- newMissedCall: session
3179
- && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
3180
- });
3235
+ const callLog = CallLog.parse(plain);
3236
+ // @TODO: FIXME add verification declined vs missed call
3237
+ callLog.newMissedCall = session
3238
+ && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
3239
+ return callLog;
3181
3240
  }
3182
3241
 
3183
3242
  static newFrom(profile ) {
@@ -3934,6 +3993,9 @@ var calldMethods = (client , baseUrl ) => ({
3934
3993
  getConferenceParticipantsAsUser: async (conferenceId ) =>
3935
3994
  client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
3936
3995
 
3996
+ getMeetingParticipantsAsUser: async (meetingUuid ) =>
3997
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
3998
+
3937
3999
  listTrunks: () => client.get(`${baseUrl}/trunks`),
3938
4000
 
3939
4001
  mute: (callId ) =>
@@ -2511,6 +2511,65 @@ class ExternalApp {
2511
2511
  }
2512
2512
  }
2513
2513
 
2514
+ //
2515
+
2516
+
2517
+
2518
+
2519
+
2520
+
2521
+
2522
+
2523
+
2524
+
2525
+
2526
+ class Meeting {
2527
+
2528
+
2529
+
2530
+
2531
+
2532
+
2533
+
2534
+
2535
+
2536
+
2537
+ static parse(plain ) {
2538
+ return new Meeting({
2539
+ guestSipAuthorization: plain.guest_sip_authorization,
2540
+ hostname: plain.hostname,
2541
+ name: plain.name,
2542
+ ownerUuids: plain.owner_uuids,
2543
+ port: plain.port,
2544
+ uuid: plain.uuid,
2545
+ number: plain.number,
2546
+ });
2547
+ }
2548
+
2549
+ static newFrom(meeting ) {
2550
+ return newFrom(meeting, Meeting);
2551
+ }
2552
+
2553
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
2554
+ this.guestSipAuthorization = guestSipAuthorization;
2555
+ this.hostname = hostname;
2556
+ this.name = name;
2557
+ this.ownerUuids = ownerUuids;
2558
+ this.port = port;
2559
+ this.uuid = uuid;
2560
+ this.number = number;
2561
+
2562
+ // Useful to compare instead of instanceof with minified code
2563
+ this.type = 'Meeting';
2564
+ }
2565
+
2566
+ getGuestSipCredentials() {
2567
+ // eslint-disable-next-line no-undef
2568
+ const [username, secret] = atob(this.guestSipAuthorization).split(':');
2569
+ return { username, secret };
2570
+ }
2571
+ }
2572
+
2514
2573
  /* */
2515
2574
 
2516
2575
  var confdMethods = (client , baseUrl ) => ({
@@ -2575,6 +2634,18 @@ var confdMethods = (client , baseUrl ) => ({
2575
2634
  return null;
2576
2635
  }
2577
2636
  },
2637
+
2638
+ createMyMeeting: (name ) =>
2639
+ client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
2640
+
2641
+ deleteMyMeeting: (meetingUuid ) =>
2642
+ client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
2643
+
2644
+ getMeeting: (meetingUuid ) =>
2645
+ client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
2646
+
2647
+ guestGetMeeting: (meetingUuid ) =>
2648
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
2578
2649
  });
2579
2650
 
2580
2651
  //
@@ -3185,7 +3256,11 @@ class CallLog {
3185
3256
  answered: plain.answered,
3186
3257
  callDirection: plain.call_direction,
3187
3258
  destination: {
3188
- extension: plain.requested_extension || plain.destination_extension,
3259
+ // @TEMP: Temporarily assuming empty numbers are meetings
3260
+ // which is admittedly a very dangerous assumption. Did i mention it was temporary?
3261
+ extension: plain.requested_extension
3262
+ || plain.destination_extension
3263
+ || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3189
3264
  name: plain.requested_name || plain.destination_name || '',
3190
3265
  },
3191
3266
  source: {
@@ -3201,27 +3276,11 @@ class CallLog {
3201
3276
  }
3202
3277
 
3203
3278
  static parseNew(plain , session ) {
3204
- return new CallLog({
3205
- answer: plain.answer ? moment(plain.answer).toDate() : null,
3206
- answered: plain.answered,
3207
- callDirection: plain.call_direction,
3208
- destination: {
3209
- extension: plain.requested_extension || plain.destination_extension,
3210
- name: plain.requested_name || plain.destination_name || '',
3211
- },
3212
- source: {
3213
- extension: plain.source_extension,
3214
- name: plain.source_name,
3215
- },
3216
- id: plain.id,
3217
- duration: (plain.duration || 0) * 1000, // duration is in seconds
3218
- start: moment(plain.start).toDate(),
3219
- end: plain.end ? moment(plain.end).toDate() : null,
3220
- recordings: Recording.parseMany(plain.recordings),
3221
- // @TODO: FIXME add verification declined vs missed call
3222
- newMissedCall: session
3223
- && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
3224
- });
3279
+ const callLog = CallLog.parse(plain);
3280
+ // @TODO: FIXME add verification declined vs missed call
3281
+ callLog.newMissedCall = session
3282
+ && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
3283
+ return callLog;
3225
3284
  }
3226
3285
 
3227
3286
  static newFrom(profile ) {
@@ -3978,6 +4037,9 @@ var calldMethods = (client , baseUrl ) => ({
3978
4037
  getConferenceParticipantsAsUser: async (conferenceId ) =>
3979
4038
  client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
3980
4039
 
4040
+ getMeetingParticipantsAsUser: async (meetingUuid ) =>
4041
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
4042
+
3981
4043
  listTrunks: () => client.get(`${baseUrl}/trunks`),
3982
4044
 
3983
4045
  mute: (callId ) =>
@@ -4712,6 +4774,8 @@ const CONFERENCE_USER_PARTICIPANT_JOINED = 'conference_user_participant_joined';
4712
4774
  const CONFERENCE_USER_PARTICIPANT_LEFT = 'conference_user_participant_left';
4713
4775
  const CONFERENCE_USER_PARTICIPANT_TALK_STARTED = 'conference_user_participant_talk_started';
4714
4776
  const CONFERENCE_USER_PARTICIPANT_TALK_STOPPED = 'conference_user_participant_talk_stopped';
4777
+ const MEETING_USER_PARTICIPANT_JOINED = 'meeting_user_participant_joined';
4778
+ const MEETING_USER_PARTICIPANT_LEFT = 'meeting_user_participant_left';
4715
4779
  const SWITCHBOARD_QUEUED_CALLS_UPDATED = 'switchboard_queued_calls_updated';
4716
4780
  const SWITCHBOARD_QUEUED_CALL_ANSWERED = 'switchboard_queued_call_answered';
4717
4781
  const SWITCHBOARD_HELD_CALLS_UPDATED = 'switchboard_held_calls_updated';
@@ -5058,6 +5122,8 @@ WebSocketClient.eventLists = [
5058
5122
  CHATD_USER_ROOM_CREATED,
5059
5123
  CONFERENCE_USER_PARTICIPANT_JOINED,
5060
5124
  CONFERENCE_USER_PARTICIPANT_LEFT,
5125
+ MEETING_USER_PARTICIPANT_JOINED,
5126
+ MEETING_USER_PARTICIPANT_LEFT,
5061
5127
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
5062
5128
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
5063
5129
  SWITCHBOARD_QUEUED_CALLS_UPDATED,
@@ -5294,7 +5360,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5294
5360
  .then(() => {
5295
5361
  if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
5296
5362
  // Add a video an empty bundle to be able to replaceTrack when joining a conference without video
5297
- this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5363
+ if (this.peerConnection.addTransceiver) {
5364
+ this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5365
+ }
5298
5366
  }
5299
5367
  })
5300
5368
  .then(() => this.createLocalOfferOrAnswer(options))
@@ -5321,12 +5389,6 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5321
5389
  };
5322
5390
  })
5323
5391
  .then((sessionDescription) => this.applyModifiers(sessionDescription, modifiers))
5324
- .then((sessionDescription) => {
5325
- // Set new constraints to avoid the constraints check issue in `sdh.getLocalMediaStream` later.
5326
- this.localMediaStreamConstraints = options.constraints;
5327
-
5328
- return sessionDescription;
5329
- })
5330
5392
  .then((sessionDescription) => ({ body: sessionDescription.sdp, contentType: 'application/sdp' }))
5331
5393
  .catch((error) => {
5332
5394
  wazoLogger.error('error when creating media', error);
@@ -5521,6 +5583,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5521
5583
 
5522
5584
  // set the transceiver direction to the answer direction
5523
5585
  this._peerConnection.getTransceivers().forEach((transceiver) => {
5586
+ if (transceiver.stopped) {
5587
+ return;
5588
+ }
5524
5589
  if (transceiver.direction /* guarding, but should always be true */) {
5525
5590
  const { receiver } = transceiver;
5526
5591
  if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
@@ -5565,10 +5630,15 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5565
5630
  if (kind !== 'audio' && kind !== 'video') {
5566
5631
  throw new Error(`Unknown new track kind ${kind}.`);
5567
5632
  }
5568
- const sender = pc.getSenders().find((otherSender) => otherSender.track && otherSender.track.kind === kind);
5633
+ const sender = pc.getSenders && pc.getSenders().find((otherSender) =>
5634
+ otherSender.track && otherSender.track.kind === kind);
5569
5635
 
5570
5636
  // Do not reuse sender video tracks in SFU
5571
5637
  if (sender && (!sfu || newTrack.kind === 'audio')) {
5638
+ if (sender.track) {
5639
+ // eslint-disable-next-line no-param-reassign
5640
+ newTrack.enabled = sender.track.enabled;
5641
+ }
5572
5642
  trackUpdates.push(
5573
5643
  new Promise((resolve) => {
5574
5644
  this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
@@ -5602,7 +5672,11 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5602
5672
  // Review: could make streamless tracks a configurable option?
5603
5673
  // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack#Usage_notes
5604
5674
  try {
5605
- pc.addTrack(newTrack, localStream);
5675
+ if (pc.addTrack) {
5676
+ pc.addTrack(newTrack, localStream);
5677
+ } else {
5678
+ pc.addStream(localStream);
5679
+ }
5606
5680
  } catch (error) {
5607
5681
  this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to add sender ${kind} track`);
5608
5682
  throw error;
@@ -5686,6 +5760,7 @@ const MAX_REGISTER_TRIES = 10;
5686
5760
 
5687
5761
 
5688
5762
 
5763
+
5689
5764
 
5690
5765
 
5691
5766
 
@@ -5712,6 +5787,7 @@ class WebRTCClient extends Emitter {
5712
5787
 
5713
5788
 
5714
5789
 
5790
+
5715
5791
 
5716
5792
  // sugar
5717
5793
 
@@ -5750,6 +5826,8 @@ class WebRTCClient extends Emitter {
5750
5826
  super();
5751
5827
  this.uaConfigOverrides = uaConfigOverrides;
5752
5828
  this.config = config;
5829
+ this.skipRegister = config.skipRegister;
5830
+
5753
5831
  this._buildConfig(config, session).then((newConfig ) => {
5754
5832
  this.config = newConfig;
5755
5833
  this.userAgent = this.createUserAgent(uaConfigOverrides);
@@ -5877,14 +5955,22 @@ class WebRTCClient extends Emitter {
5877
5955
  }
5878
5956
 
5879
5957
  register(tries = 0) {
5880
- logger.info('sdk webrtc registering...', {
5958
+ const logInfo = {
5881
5959
  userAgent: !!this.userAgent,
5882
5960
  registered: this.isRegistered(),
5883
5961
  connectionPromise: !!this.connectionPromise,
5884
5962
  registerer: !!this.registerer,
5885
5963
  waiting: this.registerer && this.registerer.waiting,
5886
5964
  tries,
5887
- });
5965
+ skipRegister: this.skipRegister,
5966
+ };
5967
+
5968
+ if (this.skipRegister) {
5969
+ logger.info('sdk webrtc skip register...', logInfo);
5970
+ return Promise.resolve();
5971
+ }
5972
+
5973
+ logger.info('sdk webrtc registering...', logInfo);
5888
5974
 
5889
5975
  if (!this.userAgent) {
5890
5976
  logger.info('sdk webrtc recreating User Agent');
@@ -6215,12 +6301,18 @@ class WebRTCClient extends Emitter {
6215
6301
  }
6216
6302
 
6217
6303
  if (pc.getSenders) {
6304
+ if (!pc.getSenders().length) {
6305
+ return false;
6306
+ }
6218
6307
  pc.getSenders().forEach(sender => {
6219
6308
  if (sender && sender.track && sender.track.kind === 'audio') {
6220
6309
  muted = muted && !sender.track.enabled;
6221
6310
  }
6222
6311
  });
6223
6312
  } else {
6313
+ if (!pc.getLocalStreams().length) {
6314
+ return false;
6315
+ }
6224
6316
  pc.getLocalStreams().forEach(stream => {
6225
6317
  stream.getAudioTracks().forEach(track => {
6226
6318
  muted = muted && !track.enabled;
@@ -6279,6 +6371,8 @@ class WebRTCClient extends Emitter {
6279
6371
  }
6280
6372
  options.sessionDescriptionHandlerOptions = {
6281
6373
  constraints: options.constraints,
6374
+ hold: true,
6375
+ conference: isConference,
6282
6376
  };
6283
6377
 
6284
6378
  // Send re-INVITE
@@ -6321,6 +6415,8 @@ class WebRTCClient extends Emitter {
6321
6415
  }
6322
6416
  options.sessionDescriptionHandlerOptions = {
6323
6417
  constraints: options.constraints,
6418
+ hold: false,
6419
+ conference: isConference,
6324
6420
  };
6325
6421
 
6326
6422
  // Send re-INVITE
@@ -6504,7 +6600,8 @@ class WebRTCClient extends Emitter {
6504
6600
  }
6505
6601
  const sdh = session.sessionDescriptionHandler;
6506
6602
  const pc = sdh.peerConnection;
6507
- const localStream = this.getLocalStream(this.getSipSessionId(session));
6603
+ const sessionId = this.getSipSessionId(session);
6604
+ const localStream = this.getLocalStream(sessionId);
6508
6605
 
6509
6606
  // Release old video stream
6510
6607
  if (localStream) {
@@ -6530,11 +6627,8 @@ class WebRTCClient extends Emitter {
6530
6627
 
6531
6628
  // let's update the local stream
6532
6629
  this.eventEmitter.emit('onVideoInputChange', stream);
6533
- try {
6534
- await sdh.setLocalMediaStream(stream);
6535
- } catch (_) {
6536
- // Nothing to do
6537
- }
6630
+ this.setLocalMediaStream(sessionId, stream);
6631
+
6538
6632
  return stream;
6539
6633
  });
6540
6634
  }
@@ -6836,9 +6930,11 @@ class WebRTCClient extends Emitter {
6836
6930
  remoteStream.removeTrack(track);
6837
6931
  });
6838
6932
 
6839
- pc.getReceivers().forEach(receiver => {
6840
- remoteStream.addTrack(receiver.track);
6841
- });
6933
+ if (pc.getReceivers) {
6934
+ pc.getReceivers().forEach(receiver => {
6935
+ remoteStream.addTrack(receiver.track);
6936
+ });
6937
+ }
6842
6938
  }
6843
6939
 
6844
6940
  getMediaConfiguration(enableVideo , conference = false, constraints = null) {
@@ -6873,6 +6969,25 @@ class WebRTCClient extends Emitter {
6873
6969
  return sessionId in this.conferences;
6874
6970
  }
6875
6971
 
6972
+ createAudioElementFor(sessionId ) {
6973
+ const audio = document.createElement('audio');
6974
+ audio.setAttribute('id', `audio-${sessionId}`);
6975
+
6976
+ if (audio.setSinkId && this.audioOutputDeviceId) {
6977
+ audio.setSinkId(this.audioOutputDeviceId);
6978
+ }
6979
+
6980
+ if (document.body) {
6981
+ document.body.appendChild(audio);
6982
+ }
6983
+ this.audioElements[sessionId] = audio;
6984
+
6985
+ audio.volume = this.audioOutputVolume;
6986
+ audio.autoplay = true;
6987
+
6988
+ return audio;
6989
+ }
6990
+
6876
6991
  _onTransportError() {
6877
6992
  this.eventEmitter.emit(TRANSPORT_ERROR);
6878
6993
  this.attemptReconnection();
@@ -7102,7 +7217,7 @@ class WebRTCClient extends Emitter {
7102
7217
  let hadRemoteVideo = false;
7103
7218
 
7104
7219
  // Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
7105
- // Becase when `onInvite` is called we already got the video track
7220
+ // Because when `onInvite` is called we already got the video track
7106
7221
  session.onInviteRequest = (request) => {
7107
7222
  hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
7108
7223
 
@@ -7177,20 +7292,10 @@ class WebRTCClient extends Emitter {
7177
7292
  const isConference = this.isConference(sessionId);
7178
7293
 
7179
7294
  if (this._hasAudio() && this._isWeb() && !(sessionId in this.audioElements)) {
7180
- const audio = document.createElement('audio');
7181
- audio.setAttribute('id', `audio-${sessionId}`);
7182
-
7183
- if (audio.setSinkId && this.audioOutputDeviceId) {
7184
- audio.setSinkId(this.audioOutputDeviceId);
7185
- }
7186
-
7187
- if (document.body) {
7188
- document.body.appendChild(audio);
7189
- }
7190
- this.audioElements[sessionId] = audio;
7295
+ this.createAudioElementFor(sessionId);
7191
7296
  }
7192
7297
 
7193
- const audioElement = this.audioElements[this.getSipSessionId(session)];
7298
+ const audioElement = this.audioElements[sessionId];
7194
7299
  const stream = newStream || this.getRemoteStream(sessionId);
7195
7300
 
7196
7301
  if (!this._isWeb() || !stream) {
@@ -465,6 +465,8 @@ const CONFERENCE_USER_PARTICIPANT_JOINED = 'conference_user_participant_joined';
465
465
  const CONFERENCE_USER_PARTICIPANT_LEFT = 'conference_user_participant_left';
466
466
  const CONFERENCE_USER_PARTICIPANT_TALK_STARTED = 'conference_user_participant_talk_started';
467
467
  const CONFERENCE_USER_PARTICIPANT_TALK_STOPPED = 'conference_user_participant_talk_stopped';
468
+ const MEETING_USER_PARTICIPANT_JOINED = 'meeting_user_participant_joined';
469
+ const MEETING_USER_PARTICIPANT_LEFT = 'meeting_user_participant_left';
468
470
  const SWITCHBOARD_QUEUED_CALLS_UPDATED = 'switchboard_queued_calls_updated';
469
471
  const SWITCHBOARD_QUEUED_CALL_ANSWERED = 'switchboard_queued_call_answered';
470
472
  const SWITCHBOARD_HELD_CALLS_UPDATED = 'switchboard_held_calls_updated';
@@ -811,6 +813,8 @@ WebSocketClient.eventLists = [
811
813
  CHATD_USER_ROOM_CREATED,
812
814
  CONFERENCE_USER_PARTICIPANT_JOINED,
813
815
  CONFERENCE_USER_PARTICIPANT_LEFT,
816
+ MEETING_USER_PARTICIPANT_JOINED,
817
+ MEETING_USER_PARTICIPANT_LEFT,
814
818
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
815
819
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
816
820
  SWITCHBOARD_QUEUED_CALLS_UPDATED,