@wazo/sdk 0.38.5 → 0.38.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/wazo-sdk.js +2 -2
- package/esm/__tests__/api-client.test.js +148 -2
- package/esm/__tests__/web-rtc-client.test.js +303 -26
- package/esm/api/calld.js +14 -0
- package/esm/api/confd.js +134 -2
- package/esm/api/ctid-ng.js +6 -0
- package/esm/api-client.js +148 -2
- package/esm/checker/Checker.js +212 -26
- package/esm/checker/checks/aor.js +148 -2
- package/esm/checker/checks/api.js +148 -2
- package/esm/checker/checks/index.js +212 -26
- package/esm/checker/checks/wazo-websocket.js +2 -0
- package/esm/checker/checks/webrtc-transport.js +210 -26
- package/esm/checker/checks/webrtc.js +210 -26
- package/esm/domain/AdHocAPIConference.js +148 -2
- package/esm/domain/Call.js +6 -0
- package/esm/domain/CallSession.js +1 -1
- package/esm/domain/Features.js +148 -2
- package/esm/domain/Meeting.js +18 -0
- package/esm/domain/MeetingAuthorization.js +70 -0
- package/esm/domain/Phone/CTIPhone.js +149 -3
- package/esm/domain/Phone/WebRTCPhone.js +3 -3
- package/esm/domain/__tests__/Call.test.js +6 -0
- package/esm/domain/__tests__/CallSession.test.js +1 -1
- package/esm/domain/__tests__/IndirectTransfer.test.js +1 -1
- package/esm/domain/__tests__/Meeting.test.js +87 -1
- package/esm/domain/__tests__/MeetingAuthorization.test.js +109 -0
- package/esm/domain/__tests__/Room.test.js +1 -1
- package/esm/index.js +258 -32
- package/esm/lib/WazoSessionDescriptionHandler.js +22 -1
- package/esm/service/CallApi.js +148 -2
- package/esm/service/getApiClient.js +148 -2
- package/esm/simple/Auth.js +258 -32
- package/esm/simple/Configuration.js +258 -32
- package/esm/simple/Directory.js +148 -2
- package/esm/simple/Phone.js +258 -32
- package/esm/simple/Websocket.js +3 -0
- package/esm/simple/index.js +258 -32
- package/esm/simple/room/LocalParticipant.js +258 -32
- package/esm/simple/room/Participant.js +258 -32
- package/esm/simple/room/RemoteParticipant.js +258 -32
- package/esm/simple/room/Room.js +258 -32
- package/esm/simple/room/SipRoom.js +258 -32
- package/esm/simple/room/Stream.js +258 -32
- package/esm/simple/room/__tests__/Participant.test.js +14747 -0
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +258 -32
- package/esm/simple/utils.js +258 -32
- package/esm/utils/__tests__/object.test.js +57 -0
- package/esm/utils/__tests__/sdp.test.js +50 -0
- package/esm/utils/__tests__/string.test.js +30 -0
- package/esm/utils/object.js +24 -0
- package/esm/utils/sdp.js +19 -1
- package/esm/utils/string.js +10 -0
- package/esm/web-rtc-client.js +210 -26
- package/esm/websocket-client.js +3 -1
- package/lib/__tests__/api-client.test.js +148 -2
- package/lib/__tests__/web-rtc-client.test.js +303 -26
- package/lib/api/calld.js +14 -0
- package/lib/api/confd.js +134 -2
- package/lib/api/ctid-ng.js +6 -0
- package/lib/api-client.js +148 -2
- package/lib/checker/Checker.js +212 -26
- package/lib/checker/checks/aor.js +148 -2
- package/lib/checker/checks/api.js +148 -2
- package/lib/checker/checks/index.js +212 -26
- package/lib/checker/checks/wazo-websocket.js +2 -0
- package/lib/checker/checks/webrtc-transport.js +210 -26
- package/lib/checker/checks/webrtc.js +210 -26
- package/lib/domain/AdHocAPIConference.js +148 -2
- package/lib/domain/Call.js +6 -0
- package/lib/domain/CallSession.js +1 -1
- package/lib/domain/Features.js +148 -2
- package/lib/domain/Meeting.js +18 -0
- package/lib/domain/MeetingAuthorization.js +79 -0
- package/lib/domain/Phone/CTIPhone.js +149 -3
- package/lib/domain/Phone/WebRTCPhone.js +3 -3
- package/lib/domain/__tests__/Call.test.js +6 -0
- package/lib/domain/__tests__/CallSession.test.js +1 -1
- package/lib/domain/__tests__/IndirectTransfer.test.js +1 -1
- package/lib/domain/__tests__/Meeting.test.js +87 -1
- package/lib/domain/__tests__/MeetingAuthorization.test.js +111 -0
- package/lib/domain/__tests__/Room.test.js +1 -1
- package/lib/index.js +258 -32
- package/lib/lib/WazoSessionDescriptionHandler.js +22 -1
- package/lib/service/CallApi.js +148 -2
- package/lib/service/getApiClient.js +148 -2
- package/lib/simple/Auth.js +258 -32
- package/lib/simple/Configuration.js +258 -32
- package/lib/simple/Directory.js +148 -2
- package/lib/simple/Phone.js +258 -32
- package/lib/simple/Websocket.js +3 -0
- package/lib/simple/index.js +258 -32
- package/lib/simple/room/LocalParticipant.js +258 -32
- package/lib/simple/room/Participant.js +258 -32
- package/lib/simple/room/RemoteParticipant.js +258 -32
- package/lib/simple/room/Room.js +258 -32
- package/lib/simple/room/SipRoom.js +258 -32
- package/lib/simple/room/Stream.js +258 -32
- package/lib/simple/room/__tests__/Participant.test.js +14757 -0
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +258 -32
- package/lib/simple/utils.js +258 -32
- package/lib/utils/__tests__/object.test.js +59 -0
- package/lib/utils/__tests__/sdp.test.js +50 -0
- package/lib/utils/__tests__/string.test.js +32 -0
- package/lib/utils/object.js +28 -0
- package/lib/utils/sdp.js +19 -0
- package/lib/utils/string.js +14 -0
- package/lib/web-rtc-client.js +210 -26
- package/lib/websocket-client.js +3 -0
- package/package.json +2 -2
- package/src/__tests__/web-rtc-client.test.js +93 -0
- package/src/api/calld.js +8 -0
- package/src/api/confd.js +43 -2
- package/src/domain/Call.js +6 -0
- package/src/domain/CallSession.js +1 -1
- package/src/domain/Meeting.js +20 -0
- package/src/domain/MeetingAuthorization.js +67 -0
- package/src/domain/Phone/WebRTCPhone.js +2 -2
- package/src/domain/__tests__/Meeting.test.js +70 -1
- package/src/domain/__tests__/MeetingAuthorization.test.js +58 -0
- package/src/lib/WazoSessionDescriptionHandler.js +5 -2
- package/src/simple/room/Participant.js +40 -0
- package/src/simple/room/Room.js +2 -2
- package/src/simple/room/SipRoom.js +1 -1
- package/src/simple/room/__tests__/Participant.test.js +81 -0
- package/src/types/WebSocketMessage.js +7 -1
- package/src/utils/__tests__/object.test.js +35 -0
- package/src/utils/__tests__/sdp.test.js +33 -1
- package/src/utils/__tests__/string.test.js +23 -0
- package/src/utils/object.js +15 -0
- package/src/utils/sdp.js +18 -0
- package/src/utils/string.js +8 -0
- package/src/web-rtc-client.js +40 -23
- package/src/websocket-client.js +2 -0
|
@@ -787,6 +787,24 @@ const fixSdp = (sdp , candidates , forcePort = true)
|
|
|
787
787
|
return fixed;
|
|
788
788
|
};
|
|
789
789
|
|
|
790
|
+
const addIcesInAllBundles = (sdp ) => {
|
|
791
|
+
const parsedSdp = sdpParser__default['default'].parse(sdp);
|
|
792
|
+
|
|
793
|
+
const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates);
|
|
794
|
+
if (!mediaWithCandidate) {
|
|
795
|
+
return sdp;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
const { candidates } = mediaWithCandidate;
|
|
799
|
+
|
|
800
|
+
parsedSdp.media = parsedSdp.media.map(media => ({
|
|
801
|
+
...media,
|
|
802
|
+
candidates: media.candidates || candidates,
|
|
803
|
+
}));
|
|
804
|
+
|
|
805
|
+
return sdpParser__default['default'].write(parsedSdp);
|
|
806
|
+
};
|
|
807
|
+
|
|
790
808
|
/* global RTCSessionDescriptionInit, navigator */
|
|
791
809
|
|
|
792
810
|
const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
|
|
@@ -916,7 +934,10 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
916
934
|
|
|
917
935
|
// Check if we got ICEs
|
|
918
936
|
if (sdp.indexOf('a=candidate') !== -1) {
|
|
919
|
-
return
|
|
937
|
+
return {
|
|
938
|
+
type: description.type,
|
|
939
|
+
sdp: addIcesInAllBundles(sdp),
|
|
940
|
+
};
|
|
920
941
|
}
|
|
921
942
|
|
|
922
943
|
wazoLogger.info('No ICE candidates found in SDP, fixing it with gathered ices', this.gatheredCandidates);
|
|
@@ -3190,6 +3211,70 @@ class ExternalApp {
|
|
|
3190
3211
|
|
|
3191
3212
|
//
|
|
3192
3213
|
|
|
3214
|
+
class MeetingAuthorization {
|
|
3215
|
+
|
|
3216
|
+
|
|
3217
|
+
|
|
3218
|
+
|
|
3219
|
+
|
|
3220
|
+
|
|
3221
|
+
constructor({
|
|
3222
|
+
meetingUuid,
|
|
3223
|
+
uuid,
|
|
3224
|
+
userUuid,
|
|
3225
|
+
userName,
|
|
3226
|
+
} = {}) {
|
|
3227
|
+
this.meetingUuid = meetingUuid;
|
|
3228
|
+
this.uuid = uuid;
|
|
3229
|
+
this.userUuid = userUuid;
|
|
3230
|
+
this.userName = userName;
|
|
3231
|
+
}
|
|
3232
|
+
|
|
3233
|
+
setStatus(status ) {
|
|
3234
|
+
this.status = status;
|
|
3235
|
+
}
|
|
3236
|
+
|
|
3237
|
+
getStatus() {
|
|
3238
|
+
return this.status;
|
|
3239
|
+
}
|
|
3240
|
+
|
|
3241
|
+
static parse(plain ) {
|
|
3242
|
+
const {
|
|
3243
|
+
meeting_uuid: meetingUuid,
|
|
3244
|
+
uuid,
|
|
3245
|
+
guest_uuid: userUuid,
|
|
3246
|
+
guest_name: userName,
|
|
3247
|
+
} = plain;
|
|
3248
|
+
|
|
3249
|
+
return new MeetingAuthorization({
|
|
3250
|
+
meetingUuid,
|
|
3251
|
+
uuid,
|
|
3252
|
+
userUuid,
|
|
3253
|
+
userName,
|
|
3254
|
+
});
|
|
3255
|
+
}
|
|
3256
|
+
|
|
3257
|
+
static parseMany(items ) {
|
|
3258
|
+
if (!items) {
|
|
3259
|
+
return [];
|
|
3260
|
+
}
|
|
3261
|
+
return items.map(MeetingAuthorization.parse);
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
|
|
3265
|
+
//
|
|
3266
|
+
|
|
3267
|
+
|
|
3268
|
+
|
|
3269
|
+
|
|
3270
|
+
|
|
3271
|
+
|
|
3272
|
+
|
|
3273
|
+
|
|
3274
|
+
|
|
3275
|
+
|
|
3276
|
+
|
|
3277
|
+
|
|
3193
3278
|
|
|
3194
3279
|
|
|
3195
3280
|
|
|
@@ -3200,6 +3285,7 @@ class ExternalApp {
|
|
|
3200
3285
|
|
|
3201
3286
|
|
|
3202
3287
|
|
|
3288
|
+
|
|
3203
3289
|
|
|
3204
3290
|
|
|
3205
3291
|
class Meeting {
|
|
@@ -3214,6 +3300,8 @@ class Meeting {
|
|
|
3214
3300
|
|
|
3215
3301
|
|
|
3216
3302
|
|
|
3303
|
+
|
|
3304
|
+
|
|
3217
3305
|
|
|
3218
3306
|
static parse(plain ) {
|
|
3219
3307
|
return new Meeting({
|
|
@@ -3226,6 +3314,7 @@ class Meeting {
|
|
|
3226
3314
|
extension: plain.exten,
|
|
3227
3315
|
persistent: plain.persistent,
|
|
3228
3316
|
creationTime: moment__default['default'](plain.creation_time).toDate(),
|
|
3317
|
+
requireAuthorization: plain.require_authorization,
|
|
3229
3318
|
});
|
|
3230
3319
|
}
|
|
3231
3320
|
|
|
@@ -3250,6 +3339,7 @@ class Meeting {
|
|
|
3250
3339
|
extension,
|
|
3251
3340
|
persistent,
|
|
3252
3341
|
creationTime,
|
|
3342
|
+
requireAuthorization,
|
|
3253
3343
|
} = {}) {
|
|
3254
3344
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
3255
3345
|
this.uri = uri;
|
|
@@ -3260,6 +3350,7 @@ class Meeting {
|
|
|
3260
3350
|
this.extension = extension;
|
|
3261
3351
|
this.persistent = persistent;
|
|
3262
3352
|
this.creationTime = creationTime;
|
|
3353
|
+
this.requireAuthorization = requireAuthorization;
|
|
3263
3354
|
|
|
3264
3355
|
// Useful to compare instead of instanceof with minified code
|
|
3265
3356
|
this.type = 'Meeting';
|
|
@@ -3270,8 +3361,32 @@ class Meeting {
|
|
|
3270
3361
|
const [username, secret] = atob(this.guestSipAuthorization).split(':');
|
|
3271
3362
|
return { username, secret };
|
|
3272
3363
|
}
|
|
3364
|
+
|
|
3273
3365
|
}
|
|
3274
3366
|
|
|
3367
|
+
//
|
|
3368
|
+
|
|
3369
|
+
const camelToUnderscore = (key ) => {
|
|
3370
|
+
if (typeof key !== 'string') {
|
|
3371
|
+
throw new Error('Input is not a string');
|
|
3372
|
+
}
|
|
3373
|
+
return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
|
|
3374
|
+
};
|
|
3375
|
+
|
|
3376
|
+
//
|
|
3377
|
+
|
|
3378
|
+
const convertKeysFromCamelToUnderscore = (args ) => {
|
|
3379
|
+
if (!args || typeof args !== 'object' || Array.isArray(args)) {
|
|
3380
|
+
throw new Error('Input is not an object');
|
|
3381
|
+
}
|
|
3382
|
+
|
|
3383
|
+
return Object.keys(args).reduce((acc, key) => {
|
|
3384
|
+
acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
|
|
3385
|
+
? convertKeysFromCamelToUnderscore(args[key]) : args[key];
|
|
3386
|
+
return acc;
|
|
3387
|
+
}, {});
|
|
3388
|
+
};
|
|
3389
|
+
|
|
3275
3390
|
/* */
|
|
3276
3391
|
|
|
3277
3392
|
var confdMethods = (client , baseUrl ) => ({
|
|
@@ -3340,8 +3455,18 @@ var confdMethods = (client , baseUrl ) => ({
|
|
|
3340
3455
|
getMyMeetings: () =>
|
|
3341
3456
|
client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
|
|
3342
3457
|
|
|
3343
|
-
createMyMeeting: (
|
|
3344
|
-
client
|
|
3458
|
+
createMyMeeting: (args ) =>
|
|
3459
|
+
client
|
|
3460
|
+
.post(`${baseUrl}/users/me/meetings`, convertKeysFromCamelToUnderscore(args))
|
|
3461
|
+
.then(Meeting.parse),
|
|
3462
|
+
|
|
3463
|
+
updateMyMeeting: (meetingUuid , data ) =>
|
|
3464
|
+
client.put(
|
|
3465
|
+
`${baseUrl}/users/me/meetings/${meetingUuid}`,
|
|
3466
|
+
convertKeysFromCamelToUnderscore(data),
|
|
3467
|
+
null,
|
|
3468
|
+
ApiRequester.successResponseParser,
|
|
3469
|
+
),
|
|
3345
3470
|
|
|
3346
3471
|
deleteMyMeeting: (meetingUuid ) =>
|
|
3347
3472
|
client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
|
|
@@ -3349,8 +3474,36 @@ var confdMethods = (client , baseUrl ) => ({
|
|
|
3349
3474
|
getMeeting: (meetingUuid ) =>
|
|
3350
3475
|
client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
3351
3476
|
|
|
3477
|
+
meetingAuthorizations: (meetingUuid ) =>
|
|
3478
|
+
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations`, null).then(MeetingAuthorization.parseMany),
|
|
3479
|
+
|
|
3480
|
+
meetingAuthorizationReject: (meetingUuid , authorizationUuid ) =>
|
|
3481
|
+
client.put(
|
|
3482
|
+
`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/reject`,
|
|
3483
|
+
{},
|
|
3484
|
+
null,
|
|
3485
|
+
ApiRequester.successResponseParser,
|
|
3486
|
+
),
|
|
3487
|
+
|
|
3488
|
+
meetingAuthorizationAccept: (meetingUuid , authorizationUuid ) =>
|
|
3489
|
+
client.put(
|
|
3490
|
+
`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/accept`,
|
|
3491
|
+
{},
|
|
3492
|
+
null,
|
|
3493
|
+
ApiRequester.successResponseParser,
|
|
3494
|
+
),
|
|
3495
|
+
|
|
3352
3496
|
guestGetMeeting: (meetingUuid ) =>
|
|
3353
3497
|
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
3498
|
+
|
|
3499
|
+
guestAuthorizationRequest: (userUuid , meetingUuid , username ) =>
|
|
3500
|
+
client
|
|
3501
|
+
.post(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations`, { guest_name: username })
|
|
3502
|
+
.then(MeetingAuthorization.parse),
|
|
3503
|
+
|
|
3504
|
+
guestAuthorizationCheck: (userUuid , meetingUuid , authorizationUuid ) =>
|
|
3505
|
+
client.get(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations/${authorizationUuid}`, null),
|
|
3506
|
+
|
|
3354
3507
|
});
|
|
3355
3508
|
|
|
3356
3509
|
//
|
|
@@ -3616,6 +3769,7 @@ const RECORD_STATE_ACTIVE = 'active';
|
|
|
3616
3769
|
|
|
3617
3770
|
|
|
3618
3771
|
|
|
3772
|
+
|
|
3619
3773
|
|
|
3620
3774
|
|
|
3621
3775
|
|
|
@@ -3626,6 +3780,7 @@ const RECORD_STATE_ACTIVE = 'active';
|
|
|
3626
3780
|
|
|
3627
3781
|
|
|
3628
3782
|
|
|
3783
|
+
|
|
3629
3784
|
|
|
3630
3785
|
|
|
3631
3786
|
|
|
@@ -3654,6 +3809,7 @@ class Call {
|
|
|
3654
3809
|
|
|
3655
3810
|
|
|
3656
3811
|
|
|
3812
|
+
|
|
3657
3813
|
|
|
3658
3814
|
|
|
3659
3815
|
|
|
@@ -3678,6 +3834,7 @@ class Call {
|
|
|
3678
3834
|
calleeNumber: plain.peer_caller_id_number,
|
|
3679
3835
|
dialedExtension: plain.dialed_extension,
|
|
3680
3836
|
isCaller: plain.is_caller,
|
|
3837
|
+
isVideo: plain.is_video,
|
|
3681
3838
|
muted: plain.muted,
|
|
3682
3839
|
onHold: plain.on_hold,
|
|
3683
3840
|
status: plain.status,
|
|
@@ -3701,6 +3858,7 @@ class Call {
|
|
|
3701
3858
|
calleeNumber,
|
|
3702
3859
|
dialedExtension,
|
|
3703
3860
|
isCaller,
|
|
3861
|
+
isVideo,
|
|
3704
3862
|
lineId,
|
|
3705
3863
|
muted,
|
|
3706
3864
|
onHold,
|
|
@@ -3724,6 +3882,7 @@ class Call {
|
|
|
3724
3882
|
this.startingTime = startingTime;
|
|
3725
3883
|
this.talkingToIds = talkingToIds || [];
|
|
3726
3884
|
this.recording = recording;
|
|
3885
|
+
this.isVideo = !!isVideo;
|
|
3727
3886
|
|
|
3728
3887
|
// Useful to compare instead of instanceof with minified code
|
|
3729
3888
|
this.type = 'Call';
|
|
@@ -4783,6 +4942,14 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
4783
4942
|
getMeetingParticipantsAsUser: async (meetingUuid ) =>
|
|
4784
4943
|
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
|
|
4785
4944
|
|
|
4945
|
+
banMeetingParticipant: (meetingUuid , participantUuid ) =>
|
|
4946
|
+
client.delete(
|
|
4947
|
+
`${baseUrl}/users/me/meetings/${meetingUuid}/participants/${participantUuid}`,
|
|
4948
|
+
null,
|
|
4949
|
+
null,
|
|
4950
|
+
ApiRequester.successResponseParser,
|
|
4951
|
+
),
|
|
4952
|
+
|
|
4786
4953
|
listTrunks: () => client.get(`${baseUrl}/trunks`),
|
|
4787
4954
|
|
|
4788
4955
|
mute: (callId ) =>
|
|
@@ -6423,41 +6590,58 @@ class WebRTCClient extends Emitter {
|
|
|
6423
6590
|
});
|
|
6424
6591
|
}
|
|
6425
6592
|
|
|
6426
|
-
changeAudioInputDevice(id , session ) {
|
|
6593
|
+
async changeAudioInputDevice(id , session , force ) {
|
|
6427
6594
|
const currentId = this.getAudioDeviceId();
|
|
6428
6595
|
logger.info('setting audio input device', { id, currentId, session: !!session });
|
|
6429
6596
|
|
|
6430
|
-
if (id === currentId) {
|
|
6597
|
+
if (!force && id === currentId) {
|
|
6431
6598
|
return null;
|
|
6432
6599
|
}
|
|
6433
6600
|
|
|
6601
|
+
// in order to handle an audio track change for default devices
|
|
6602
|
+
// we need the actual id of the device (not 'default')
|
|
6603
|
+
let deviceId = id;
|
|
6604
|
+
if (id === 'default' && navigator.mediaDevices) {
|
|
6605
|
+
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
6606
|
+
const defaultDevice = devices.find(device => device.deviceId === 'default');
|
|
6607
|
+
if (defaultDevice) {
|
|
6608
|
+
const deviceLabel = defaultDevice.label.replace('Default - ', '');
|
|
6609
|
+
const targetDevice = devices.find(device => device.label === deviceLabel);
|
|
6610
|
+
if (targetDevice) {
|
|
6611
|
+
deviceId = targetDevice.deviceId;
|
|
6612
|
+
if (!force && deviceId === currentId) {
|
|
6613
|
+
return null;
|
|
6614
|
+
}
|
|
6615
|
+
}
|
|
6616
|
+
}
|
|
6617
|
+
}
|
|
6618
|
+
|
|
6434
6619
|
// let's update the local audio value
|
|
6435
6620
|
if (this.audio) {
|
|
6436
6621
|
this.audio = {
|
|
6437
6622
|
deviceId: {
|
|
6438
|
-
exact:
|
|
6623
|
+
exact: deviceId,
|
|
6439
6624
|
},
|
|
6440
6625
|
};
|
|
6441
6626
|
}
|
|
6442
6627
|
|
|
6443
|
-
if (session) {
|
|
6628
|
+
if (session && navigator.mediaDevices) {
|
|
6444
6629
|
const sdh = session.sessionDescriptionHandler;
|
|
6445
6630
|
const pc = sdh.peerConnection;
|
|
6446
6631
|
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6632
|
+
const constraints = { audio: { deviceId: { exact: deviceId } } };
|
|
6633
|
+
const stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
6634
|
+
const audioTrack = stream.getAudioTracks()[0];
|
|
6635
|
+
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
6451
6636
|
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
}
|
|
6456
|
-
sender.replaceTrack(audioTrack);
|
|
6637
|
+
if (sender) {
|
|
6638
|
+
if (sender.track) {
|
|
6639
|
+
audioTrack.enabled = sender.track.enabled;
|
|
6457
6640
|
}
|
|
6641
|
+
sender.replaceTrack(audioTrack);
|
|
6642
|
+
}
|
|
6458
6643
|
|
|
6459
|
-
|
|
6460
|
-
});
|
|
6644
|
+
return stream;
|
|
6461
6645
|
}
|
|
6462
6646
|
}
|
|
6463
6647
|
|
|
@@ -6477,14 +6661,14 @@ class WebRTCClient extends Emitter {
|
|
|
6477
6661
|
return null;
|
|
6478
6662
|
}
|
|
6479
6663
|
|
|
6480
|
-
// let's
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
}
|
|
6487
|
-
}
|
|
6664
|
+
// let's make sure we don't lose other video constraints settings -- width, height, frameRate...
|
|
6665
|
+
const videoObject = typeof this.video === 'object' ? this.video : {};
|
|
6666
|
+
this.video = {
|
|
6667
|
+
...videoObject,
|
|
6668
|
+
deviceId: {
|
|
6669
|
+
exact: id,
|
|
6670
|
+
},
|
|
6671
|
+
};
|
|
6488
6672
|
}
|
|
6489
6673
|
|
|
6490
6674
|
changeSessionVideoInputDevice(id , session ) {
|
|
@@ -7611,3 +7795,96 @@ describe('WebRTC client', () => {
|
|
|
7611
7795
|
expect(client.isAudioMuted(oldKindUnmuted)).toBeFalsy();
|
|
7612
7796
|
});
|
|
7613
7797
|
});
|
|
7798
|
+
|
|
7799
|
+
describe('changeAudioInputDevice', () => {
|
|
7800
|
+
const defaultId = 'default';
|
|
7801
|
+
const deviceId = 'device1';
|
|
7802
|
+
const constraints = { audio: { deviceId: { exact: defaultId } }, video: null };
|
|
7803
|
+
|
|
7804
|
+
const session = {
|
|
7805
|
+
sessionDescriptionHandler: {
|
|
7806
|
+
peerConnection: {
|
|
7807
|
+
getSenders: () => [{ track: { kind: 'audio', enabled: true } }],
|
|
7808
|
+
},
|
|
7809
|
+
},
|
|
7810
|
+
};
|
|
7811
|
+
|
|
7812
|
+
const stream = {};
|
|
7813
|
+
const getAudioTracksMock = jest.fn(() => []);
|
|
7814
|
+
Object.defineProperty(stream, 'getAudioTracks', {
|
|
7815
|
+
value: getAudioTracksMock,
|
|
7816
|
+
});
|
|
7817
|
+
|
|
7818
|
+
const getUserMediaMock = jest.fn(async () => {
|
|
7819
|
+
return new Promise(resolve => {
|
|
7820
|
+
resolve(stream);
|
|
7821
|
+
});
|
|
7822
|
+
});
|
|
7823
|
+
|
|
7824
|
+
const devices = [
|
|
7825
|
+
{ deviceId: 'default', kind: 'audioinput', label: 'Default - Fake Microphone', groupId: 'fak3Gr0up3' },
|
|
7826
|
+
{ deviceId: 'fak3d3v1c3', kind: 'audioinput', label: 'Fake Microphone', groupId: 'fak3Gr0up3' },
|
|
7827
|
+
];
|
|
7828
|
+
const enumerateDevicesMock = jest.fn(async () => {
|
|
7829
|
+
return new Promise(resolve => {
|
|
7830
|
+
resolve(devices);
|
|
7831
|
+
});
|
|
7832
|
+
});
|
|
7833
|
+
|
|
7834
|
+
Object.defineProperty(global.navigator, 'mediaDevices', {
|
|
7835
|
+
value: {
|
|
7836
|
+
getUserMedia: getUserMediaMock,
|
|
7837
|
+
enumerateDevices: enumerateDevicesMock,
|
|
7838
|
+
},
|
|
7839
|
+
});
|
|
7840
|
+
|
|
7841
|
+
it('should change the audio input track if the provided id is different', async () => {
|
|
7842
|
+
client.setMediaConstraints(constraints);
|
|
7843
|
+
expect(client.getAudioDeviceId()).toBe(defaultId);
|
|
7844
|
+
const result = await client.changeAudioInputDevice(deviceId, session);
|
|
7845
|
+
expect(result).toBeTruthy();
|
|
7846
|
+
});
|
|
7847
|
+
|
|
7848
|
+
it('should NOT change the audio input track if the provided id is the same', async () => {
|
|
7849
|
+
client.setMediaConstraints(constraints);
|
|
7850
|
+
expect(client.getAudioDeviceId()).toBe(defaultId);
|
|
7851
|
+
const result = await client.changeAudioInputDevice(defaultId, session);
|
|
7852
|
+
expect(result).toBeFalsy();
|
|
7853
|
+
});
|
|
7854
|
+
|
|
7855
|
+
it('should change the audio input track if the provided id is the same and force param is TRUE', async () => {
|
|
7856
|
+
client.setMediaConstraints(constraints);
|
|
7857
|
+
expect(client.getAudioDeviceId()).toBe(defaultId);
|
|
7858
|
+
const result = await client.changeAudioInputDevice(defaultId, session, true);
|
|
7859
|
+
expect(result).toBeTruthy();
|
|
7860
|
+
});
|
|
7861
|
+
|
|
7862
|
+
describe('setVideoInputDevice', () => {
|
|
7863
|
+
it('should retain its original video values', () => {
|
|
7864
|
+
const video = { height: { min: 480, max: 720 }, width: { min: 640, max: 1280 } };
|
|
7865
|
+
|
|
7866
|
+
client.video = video;
|
|
7867
|
+
client.setVideoInputDevice(deviceId);
|
|
7868
|
+
expect(client.video).toEqual({ ...video, deviceId: { exact: deviceId } });
|
|
7869
|
+
});
|
|
7870
|
+
|
|
7871
|
+
it('should set deviceId when video\'s original value is true', () => {
|
|
7872
|
+
client.video = true;
|
|
7873
|
+
client.setVideoInputDevice(deviceId);
|
|
7874
|
+
expect(client.video).toEqual({ deviceId: { exact: deviceId } });
|
|
7875
|
+
});
|
|
7876
|
+
|
|
7877
|
+
it('should set deviceId when video\'s original value is not set', () => {
|
|
7878
|
+
client.video = undefined;
|
|
7879
|
+
client.setVideoInputDevice(deviceId);
|
|
7880
|
+
expect(client.video).toEqual({ deviceId: { exact: deviceId } });
|
|
7881
|
+
});
|
|
7882
|
+
|
|
7883
|
+
it('should NOT set deviceId when its value does not change', () => {
|
|
7884
|
+
client.video = { deviceId: { exact: deviceId } };
|
|
7885
|
+
const result = client.setVideoInputDevice(deviceId);
|
|
7886
|
+
expect(result).toEqual(null);
|
|
7887
|
+
expect(client.video).toEqual({ deviceId: { exact: deviceId } });
|
|
7888
|
+
});
|
|
7889
|
+
});
|
|
7890
|
+
});
|
package/lib/api/calld.js
CHANGED
|
@@ -974,6 +974,7 @@ const RECORD_STATE_ACTIVE = 'active';
|
|
|
974
974
|
|
|
975
975
|
|
|
976
976
|
|
|
977
|
+
|
|
977
978
|
|
|
978
979
|
|
|
979
980
|
|
|
@@ -984,6 +985,7 @@ const RECORD_STATE_ACTIVE = 'active';
|
|
|
984
985
|
|
|
985
986
|
|
|
986
987
|
|
|
988
|
+
|
|
987
989
|
|
|
988
990
|
|
|
989
991
|
|
|
@@ -1012,6 +1014,7 @@ class Call {
|
|
|
1012
1014
|
|
|
1013
1015
|
|
|
1014
1016
|
|
|
1017
|
+
|
|
1015
1018
|
|
|
1016
1019
|
|
|
1017
1020
|
|
|
@@ -1036,6 +1039,7 @@ class Call {
|
|
|
1036
1039
|
calleeNumber: plain.peer_caller_id_number,
|
|
1037
1040
|
dialedExtension: plain.dialed_extension,
|
|
1038
1041
|
isCaller: plain.is_caller,
|
|
1042
|
+
isVideo: plain.is_video,
|
|
1039
1043
|
muted: plain.muted,
|
|
1040
1044
|
onHold: plain.on_hold,
|
|
1041
1045
|
status: plain.status,
|
|
@@ -1059,6 +1063,7 @@ class Call {
|
|
|
1059
1063
|
calleeNumber,
|
|
1060
1064
|
dialedExtension,
|
|
1061
1065
|
isCaller,
|
|
1066
|
+
isVideo,
|
|
1062
1067
|
lineId,
|
|
1063
1068
|
muted,
|
|
1064
1069
|
onHold,
|
|
@@ -1082,6 +1087,7 @@ class Call {
|
|
|
1082
1087
|
this.startingTime = startingTime;
|
|
1083
1088
|
this.talkingToIds = talkingToIds || [];
|
|
1084
1089
|
this.recording = recording;
|
|
1090
|
+
this.isVideo = !!isVideo;
|
|
1085
1091
|
|
|
1086
1092
|
// Useful to compare instead of instanceof with minified code
|
|
1087
1093
|
this.type = 'Call';
|
|
@@ -1395,6 +1401,14 @@ var calld = (client , baseUrl ) => ({
|
|
|
1395
1401
|
getMeetingParticipantsAsUser: async (meetingUuid ) =>
|
|
1396
1402
|
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
|
|
1397
1403
|
|
|
1404
|
+
banMeetingParticipant: (meetingUuid , participantUuid ) =>
|
|
1405
|
+
client.delete(
|
|
1406
|
+
`${baseUrl}/users/me/meetings/${meetingUuid}/participants/${participantUuid}`,
|
|
1407
|
+
null,
|
|
1408
|
+
null,
|
|
1409
|
+
ApiRequester.successResponseParser,
|
|
1410
|
+
),
|
|
1411
|
+
|
|
1398
1412
|
listTrunks: () => client.get(`${baseUrl}/trunks`),
|
|
1399
1413
|
|
|
1400
1414
|
mute: (callId ) =>
|