@wazo/sdk 0.37.16 → 0.37.20
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/dist/wazo-sdk.js +5 -5
- package/esm/__tests__/api-client.test.js +9 -5
- package/esm/__tests__/web-rtc-client.test.js +69 -19
- package/esm/api/agentd.js +1 -1
- package/esm/api/amid.js +1 -1
- package/esm/api/application.js +1 -1
- package/esm/api/auth.js +1 -1
- package/esm/api/call-logd.js +3 -3
- package/esm/api/calld.js +1 -1
- package/esm/api/chatd.js +1 -1
- package/esm/api/confd.js +7 -3
- package/esm/api/ctid-ng.js +1 -1
- package/esm/api/dird.js +1 -1
- package/esm/api/webhookd.js +1 -1
- package/esm/api-client.js +9 -5
- package/esm/checker/Checker.js +69 -19
- package/esm/checker/checks/aor.js +9 -5
- package/esm/checker/checks/api.js +9 -5
- package/esm/checker/checks/index.js +69 -19
- package/esm/checker/checks/wazo-websocket.js +1 -1
- package/esm/checker/checks/webrtc-transport.js +69 -19
- package/esm/checker/checks/webrtc.js +69 -19
- package/esm/domain/AdHocAPIConference.js +9 -5
- package/esm/domain/CallLog.js +2 -2
- package/esm/domain/Features.js +9 -5
- package/esm/domain/Meeting.js +6 -2
- package/esm/domain/Phone/CTIPhone.js +9 -5
- package/esm/domain/Phone/WebRTCPhone.js +9 -2
- package/esm/domain/Recording.js +1 -1
- package/esm/domain/__tests__/CallLog.test.js +2 -2
- package/esm/index.js +77 -19
- package/esm/lib/WazoSessionDescriptionHandler.js +1 -1
- package/esm/service/CallApi.js +9 -5
- package/esm/service/IssueReporter.js +1 -1
- package/esm/service/__tests__/IssueReporter.test.js +1 -1
- package/esm/service/getApiClient.js +9 -5
- package/esm/simple/Auth.js +77 -19
- package/esm/simple/Configuration.js +77 -19
- package/esm/simple/Directory.js +9 -5
- package/esm/simple/Phone.js +77 -19
- package/esm/simple/Websocket.js +1 -1
- package/esm/simple/index.js +77 -19
- package/esm/simple/room/LocalParticipant.js +77 -19
- package/esm/simple/room/Participant.js +77 -19
- package/esm/simple/room/RemoteParticipant.js +77 -19
- package/esm/simple/room/Room.js +77 -19
- package/esm/simple/room/SipRoom.js +77 -19
- package/esm/simple/room/Stream.js +77 -19
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +77 -19
- package/esm/simple/utils.js +77 -19
- package/esm/utils/__tests__/api-requester.test.js +1 -1
- package/esm/utils/api-requester.js +1 -1
- package/esm/web-rtc-client.js +69 -19
- package/esm/websocket-client.js +1 -1
- package/lib/__tests__/api-client.test.js +9 -5
- package/lib/__tests__/web-rtc-client.test.js +69 -19
- package/lib/api/agentd.js +1 -1
- package/lib/api/amid.js +1 -1
- package/lib/api/application.js +1 -1
- package/lib/api/auth.js +1 -1
- package/lib/api/call-logd.js +3 -3
- package/lib/api/calld.js +1 -1
- package/lib/api/chatd.js +1 -1
- package/lib/api/confd.js +7 -3
- package/lib/api/ctid-ng.js +1 -1
- package/lib/api/dird.js +1 -1
- package/lib/api/webhookd.js +1 -1
- package/lib/api-client.js +9 -5
- package/lib/checker/Checker.js +69 -19
- package/lib/checker/checks/aor.js +9 -5
- package/lib/checker/checks/api.js +9 -5
- package/lib/checker/checks/index.js +69 -19
- package/lib/checker/checks/wazo-websocket.js +1 -1
- package/lib/checker/checks/webrtc-transport.js +69 -19
- package/lib/checker/checks/webrtc.js +69 -19
- package/lib/domain/AdHocAPIConference.js +9 -5
- package/lib/domain/CallLog.js +2 -2
- package/lib/domain/Features.js +9 -5
- package/lib/domain/Meeting.js +6 -2
- package/lib/domain/Phone/CTIPhone.js +9 -5
- package/lib/domain/Phone/WebRTCPhone.js +9 -1
- package/lib/domain/Recording.js +1 -1
- package/lib/domain/__tests__/CallLog.test.js +2 -2
- package/lib/index.js +77 -19
- package/lib/lib/WazoSessionDescriptionHandler.js +1 -1
- package/lib/service/CallApi.js +9 -5
- package/lib/service/IssueReporter.js +1 -1
- package/lib/service/__tests__/IssueReporter.test.js +1 -1
- package/lib/service/getApiClient.js +9 -5
- package/lib/simple/Auth.js +77 -19
- package/lib/simple/Configuration.js +77 -19
- package/lib/simple/Directory.js +9 -5
- package/lib/simple/Phone.js +77 -19
- package/lib/simple/Websocket.js +1 -1
- package/lib/simple/index.js +77 -19
- package/lib/simple/room/LocalParticipant.js +77 -19
- package/lib/simple/room/Participant.js +77 -19
- package/lib/simple/room/RemoteParticipant.js +77 -19
- package/lib/simple/room/Room.js +77 -19
- package/lib/simple/room/SipRoom.js +77 -19
- package/lib/simple/room/Stream.js +77 -19
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +77 -19
- package/lib/simple/utils.js +77 -19
- package/lib/utils/__tests__/api-requester.test.js +1 -1
- package/lib/utils/api-requester.js +1 -1
- package/lib/web-rtc-client.js +69 -19
- package/lib/websocket-client.js +1 -1
- package/package.json +2 -2
- package/src/domain/CallLog.js +1 -1
- package/src/domain/Meeting.js +6 -2
- package/src/domain/Phone/WebRTCPhone.js +7 -0
- package/src/domain/Recording.js +1 -1
- package/src/service/IssueReporter.js +1 -1
- package/src/web-rtc-client.js +60 -14
package/esm/checker/Checker.js
CHANGED
|
@@ -400,7 +400,7 @@ class IssueReporter {
|
|
|
400
400
|
payload._retry = retry + 1;
|
|
401
401
|
}
|
|
402
402
|
|
|
403
|
-
this._sendDebugToGrafana(
|
|
403
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
404
404
|
}, 5000 + retry * 1000);
|
|
405
405
|
});
|
|
406
406
|
}
|
|
@@ -2603,7 +2603,8 @@ class ExternalApp {
|
|
|
2603
2603
|
|
|
2604
2604
|
|
|
2605
2605
|
|
|
2606
|
-
|
|
2606
|
+
|
|
2607
|
+
|
|
2607
2608
|
|
|
2608
2609
|
|
|
2609
2610
|
class Meeting {
|
|
@@ -2615,6 +2616,7 @@ class Meeting {
|
|
|
2615
2616
|
|
|
2616
2617
|
|
|
2617
2618
|
|
|
2619
|
+
|
|
2618
2620
|
|
|
2619
2621
|
|
|
2620
2622
|
static parse(plain ) {
|
|
@@ -2626,6 +2628,7 @@ class Meeting {
|
|
|
2626
2628
|
port: plain.port,
|
|
2627
2629
|
uuid: plain.uuid,
|
|
2628
2630
|
number: plain.number,
|
|
2631
|
+
persistent: plain.persistent,
|
|
2629
2632
|
});
|
|
2630
2633
|
}
|
|
2631
2634
|
|
|
@@ -2633,7 +2636,7 @@ class Meeting {
|
|
|
2633
2636
|
return newFrom(meeting, Meeting);
|
|
2634
2637
|
}
|
|
2635
2638
|
|
|
2636
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
2639
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
2637
2640
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2638
2641
|
this.uri = uri;
|
|
2639
2642
|
this.name = name;
|
|
@@ -2641,6 +2644,7 @@ class Meeting {
|
|
|
2641
2644
|
this.port = port;
|
|
2642
2645
|
this.uuid = uuid;
|
|
2643
2646
|
this.number = number;
|
|
2647
|
+
this.persistent = persistent;
|
|
2644
2648
|
|
|
2645
2649
|
// Useful to compare instead of instanceof with minified code
|
|
2646
2650
|
this.type = 'Meeting';
|
|
@@ -3230,7 +3234,7 @@ class Recording {
|
|
|
3230
3234
|
|
|
3231
3235
|
|
|
3232
3236
|
|
|
3233
|
-
static parseMany(recordings
|
|
3237
|
+
static parseMany(recordings = []) {
|
|
3234
3238
|
return recordings.map(item => Recording.parse(item));
|
|
3235
3239
|
}
|
|
3236
3240
|
|
|
@@ -3356,7 +3360,7 @@ class CallLog {
|
|
|
3356
3360
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3357
3361
|
start: moment(plain.start).toDate(),
|
|
3358
3362
|
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3359
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3363
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3360
3364
|
});
|
|
3361
3365
|
}
|
|
3362
3366
|
|
|
@@ -5871,6 +5875,7 @@ const ON_REINVITE = 'reinvite';
|
|
|
5871
5875
|
const ON_ERROR = 'onError';
|
|
5872
5876
|
const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
|
|
5873
5877
|
const ON_NETWORK_STATS = 'onNetworkStats';
|
|
5878
|
+
const ON_DISCONNECTED = 'onDisconnected';
|
|
5874
5879
|
class CanceledCallError extends Error {}
|
|
5875
5880
|
|
|
5876
5881
|
const MAX_REGISTER_TRIES = 10;
|
|
@@ -5944,6 +5949,7 @@ class WebRTCClient extends Emitter {
|
|
|
5944
5949
|
|
|
5945
5950
|
|
|
5946
5951
|
|
|
5952
|
+
|
|
5947
5953
|
|
|
5948
5954
|
static isAPrivateIp(ip ) {
|
|
5949
5955
|
const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
|
|
@@ -6009,6 +6015,7 @@ class WebRTCClient extends Emitter {
|
|
|
6009
6015
|
this.ON_ERROR = ON_ERROR;
|
|
6010
6016
|
this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
|
|
6011
6017
|
this.ON_NETWORK_STATS = ON_NETWORK_STATS;
|
|
6018
|
+
this.ON_DISCONNECTED = ON_DISCONNECTED;
|
|
6012
6019
|
}
|
|
6013
6020
|
|
|
6014
6021
|
configureMedia(media ) {
|
|
@@ -6610,7 +6617,7 @@ class WebRTCClient extends Emitter {
|
|
|
6610
6617
|
// We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
|
|
6611
6618
|
const transceivers = pc.getTransceivers();
|
|
6612
6619
|
const transceiverIdx = lastIndexOf(transceivers, transceiver =>
|
|
6613
|
-
transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
|
|
6620
|
+
transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
|
|
6614
6621
|
|
|
6615
6622
|
videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
|
|
6616
6623
|
} else {
|
|
@@ -6856,10 +6863,13 @@ class WebRTCClient extends Emitter {
|
|
|
6856
6863
|
return null;
|
|
6857
6864
|
}
|
|
6858
6865
|
|
|
6859
|
-
// let's update the local value
|
|
6860
|
-
if (this.audio
|
|
6861
|
-
|
|
6862
|
-
|
|
6866
|
+
// let's update the local audio value
|
|
6867
|
+
if (this.audio) {
|
|
6868
|
+
this.audio = {
|
|
6869
|
+
deviceId: {
|
|
6870
|
+
exact: id,
|
|
6871
|
+
},
|
|
6872
|
+
};
|
|
6863
6873
|
}
|
|
6864
6874
|
|
|
6865
6875
|
if (session) {
|
|
@@ -6872,6 +6882,9 @@ class WebRTCClient extends Emitter {
|
|
|
6872
6882
|
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
6873
6883
|
|
|
6874
6884
|
if (sender) {
|
|
6885
|
+
if (sender.track) {
|
|
6886
|
+
audioTrack.enabled = sender.track.enabled;
|
|
6887
|
+
}
|
|
6875
6888
|
sender.replaceTrack(audioTrack);
|
|
6876
6889
|
}
|
|
6877
6890
|
|
|
@@ -6896,7 +6909,7 @@ class WebRTCClient extends Emitter {
|
|
|
6896
6909
|
return null;
|
|
6897
6910
|
}
|
|
6898
6911
|
|
|
6899
|
-
// let's update the local value
|
|
6912
|
+
// let's update the local video value
|
|
6900
6913
|
if (this.video) {
|
|
6901
6914
|
this.video = {
|
|
6902
6915
|
deviceId: {
|
|
@@ -6931,12 +6944,21 @@ class WebRTCClient extends Emitter {
|
|
|
6931
6944
|
return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
|
|
6932
6945
|
const videoTrack = stream.getVideoTracks()[0];
|
|
6933
6946
|
let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
|
|
6947
|
+
let wasTrackEnabled = false;
|
|
6934
6948
|
if (!sender) {
|
|
6935
6949
|
sender = pc && pc.getSenders().find(s => !s.track);
|
|
6936
6950
|
}
|
|
6937
6951
|
|
|
6938
6952
|
if (sender) {
|
|
6939
|
-
|
|
6953
|
+
// No video track means video not enabled
|
|
6954
|
+
wasTrackEnabled = sender.track ? sender.track.enabled : false;
|
|
6955
|
+
videoTrack.enabled = wasTrackEnabled;
|
|
6956
|
+
|
|
6957
|
+
if (!wasTrackEnabled) {
|
|
6958
|
+
videoTrack.stop();
|
|
6959
|
+
}
|
|
6960
|
+
|
|
6961
|
+
sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
|
|
6940
6962
|
}
|
|
6941
6963
|
|
|
6942
6964
|
// let's update the local stream
|
|
@@ -7620,6 +7642,7 @@ class WebRTCClient extends Emitter {
|
|
|
7620
7642
|
|
|
7621
7643
|
this.updateRemoteStream(this.getSipSessionId(session));
|
|
7622
7644
|
|
|
7645
|
+
const pc = session.sessionDescriptionHandler.peerConnection;
|
|
7623
7646
|
const onTrack = (event ) => {
|
|
7624
7647
|
const isAudioOnly = this._isAudioOnly(session);
|
|
7625
7648
|
const { kind, label, readyState, id, muted } = event.track;
|
|
@@ -7639,6 +7662,12 @@ class WebRTCClient extends Emitter {
|
|
|
7639
7662
|
|
|
7640
7663
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
7641
7664
|
|
|
7665
|
+
pc.oniceconnectionstatechange = () => {
|
|
7666
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
7667
|
+
this.eventEmitter.emit(ON_DISCONNECTED);
|
|
7668
|
+
}
|
|
7669
|
+
};
|
|
7670
|
+
|
|
7642
7671
|
if (withEvent) {
|
|
7643
7672
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
7644
7673
|
}
|
|
@@ -7850,25 +7879,33 @@ class WebRTCClient extends Emitter {
|
|
|
7850
7879
|
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
7851
7880
|
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
7852
7881
|
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
7882
|
+
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
7883
|
+
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
7853
7884
|
let audioBytesSent = 0;
|
|
7854
7885
|
let audioBytesReceived = 0;
|
|
7855
7886
|
let videoBytesSent = 0;
|
|
7856
7887
|
let videoBytesReceived = 0;
|
|
7888
|
+
let transportSent = 0;
|
|
7889
|
+
let transportReceived = 0;
|
|
7890
|
+
let packetsLost = 0;
|
|
7857
7891
|
|
|
7858
7892
|
stats.forEach(report => {
|
|
7859
7893
|
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
7894
|
+
audioBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7895
|
+
}
|
|
7896
|
+
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
7860
7897
|
audioBytesSent += report.bytesSent;
|
|
7861
7898
|
}
|
|
7862
7899
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7863
|
-
videoBytesSent += report.bytesSent;
|
|
7900
|
+
videoBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7864
7901
|
}
|
|
7865
7902
|
if (report.type === 'inbound-rtp' && report.kind === 'audio') {
|
|
7866
|
-
|
|
7903
|
+
packetsLost += report.packetsLost;
|
|
7867
7904
|
networkStats.packetsReceived = report.packetsReceived;
|
|
7868
|
-
audioBytesReceived += report.bytesReceived;
|
|
7905
|
+
audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7869
7906
|
}
|
|
7870
7907
|
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
7871
|
-
videoBytesReceived += report.bytesReceived;
|
|
7908
|
+
videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7872
7909
|
}
|
|
7873
7910
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7874
7911
|
if ('framesPerSecond' in report) {
|
|
@@ -7880,19 +7917,32 @@ class WebRTCClient extends Emitter {
|
|
|
7880
7917
|
}
|
|
7881
7918
|
}
|
|
7882
7919
|
if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
|
|
7920
|
+
packetsLost += report.packetsLost;
|
|
7883
7921
|
networkStats.roundTripTime = report.roundTripTime;
|
|
7884
7922
|
networkStats.jitter = report.jitter;
|
|
7885
7923
|
}
|
|
7924
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
|
|
7925
|
+
packetsLost += report.packetsLost;
|
|
7926
|
+
}
|
|
7927
|
+
if (report.type === 'transport') {
|
|
7928
|
+
transportSent += report.bytesSent;
|
|
7929
|
+
transportReceived += report.bytesReceived;
|
|
7930
|
+
}
|
|
7886
7931
|
});
|
|
7887
7932
|
|
|
7933
|
+
networkStats.packetsLost = packetsLost;
|
|
7888
7934
|
networkStats.audioBytesSent = audioBytesSent;
|
|
7889
7935
|
networkStats.audioBytesReceived = audioBytesReceived;
|
|
7890
7936
|
networkStats.videoBytesSent = videoBytesSent;
|
|
7891
7937
|
networkStats.videoBytesReceived = videoBytesReceived;
|
|
7938
|
+
networkStats.transportSent = transportSent;
|
|
7939
|
+
networkStats.transportReceived = transportReceived;
|
|
7940
|
+
|
|
7941
|
+
const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
|
|
7942
|
+
+ (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
|
|
7943
|
+
+ (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
|
|
7892
7944
|
|
|
7893
|
-
networkStats.bandwidth =
|
|
7894
|
-
+ (networkStats.videoBytesSent - lastVideoSent) + (networkStats.audioBytesReceived - lastAudioReceived)
|
|
7895
|
-
+ (networkStats.videoBytesReceived - lastVideoReceived);
|
|
7945
|
+
networkStats.bandwidth = bandwidth;
|
|
7896
7946
|
|
|
7897
7947
|
this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
|
|
7898
7948
|
this.sessionNetworkStats[sessionId].push(networkStats);
|
|
@@ -382,7 +382,7 @@ class IssueReporter {
|
|
|
382
382
|
payload._retry = retry + 1;
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
-
this._sendDebugToGrafana(
|
|
385
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
386
386
|
}, 5000 + retry * 1000);
|
|
387
387
|
});
|
|
388
388
|
}
|
|
@@ -2585,7 +2585,8 @@ class ExternalApp {
|
|
|
2585
2585
|
|
|
2586
2586
|
|
|
2587
2587
|
|
|
2588
|
-
|
|
2588
|
+
|
|
2589
|
+
|
|
2589
2590
|
|
|
2590
2591
|
|
|
2591
2592
|
class Meeting {
|
|
@@ -2597,6 +2598,7 @@ class Meeting {
|
|
|
2597
2598
|
|
|
2598
2599
|
|
|
2599
2600
|
|
|
2601
|
+
|
|
2600
2602
|
|
|
2601
2603
|
|
|
2602
2604
|
static parse(plain ) {
|
|
@@ -2608,6 +2610,7 @@ class Meeting {
|
|
|
2608
2610
|
port: plain.port,
|
|
2609
2611
|
uuid: plain.uuid,
|
|
2610
2612
|
number: plain.number,
|
|
2613
|
+
persistent: plain.persistent,
|
|
2611
2614
|
});
|
|
2612
2615
|
}
|
|
2613
2616
|
|
|
@@ -2615,7 +2618,7 @@ class Meeting {
|
|
|
2615
2618
|
return newFrom(meeting, Meeting);
|
|
2616
2619
|
}
|
|
2617
2620
|
|
|
2618
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
2621
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
2619
2622
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2620
2623
|
this.uri = uri;
|
|
2621
2624
|
this.name = name;
|
|
@@ -2623,6 +2626,7 @@ class Meeting {
|
|
|
2623
2626
|
this.port = port;
|
|
2624
2627
|
this.uuid = uuid;
|
|
2625
2628
|
this.number = number;
|
|
2629
|
+
this.persistent = persistent;
|
|
2626
2630
|
|
|
2627
2631
|
// Useful to compare instead of instanceof with minified code
|
|
2628
2632
|
this.type = 'Meeting';
|
|
@@ -3186,7 +3190,7 @@ class Recording {
|
|
|
3186
3190
|
|
|
3187
3191
|
|
|
3188
3192
|
|
|
3189
|
-
static parseMany(recordings
|
|
3193
|
+
static parseMany(recordings = []) {
|
|
3190
3194
|
return recordings.map(item => Recording.parse(item));
|
|
3191
3195
|
}
|
|
3192
3196
|
|
|
@@ -3312,7 +3316,7 @@ class CallLog {
|
|
|
3312
3316
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3313
3317
|
start: moment(plain.start).toDate(),
|
|
3314
3318
|
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3315
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3319
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3316
3320
|
});
|
|
3317
3321
|
}
|
|
3318
3322
|
|
|
@@ -382,7 +382,7 @@ class IssueReporter {
|
|
|
382
382
|
payload._retry = retry + 1;
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
-
this._sendDebugToGrafana(
|
|
385
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
386
386
|
}, 5000 + retry * 1000);
|
|
387
387
|
});
|
|
388
388
|
}
|
|
@@ -2585,7 +2585,8 @@ class ExternalApp {
|
|
|
2585
2585
|
|
|
2586
2586
|
|
|
2587
2587
|
|
|
2588
|
-
|
|
2588
|
+
|
|
2589
|
+
|
|
2589
2590
|
|
|
2590
2591
|
|
|
2591
2592
|
class Meeting {
|
|
@@ -2597,6 +2598,7 @@ class Meeting {
|
|
|
2597
2598
|
|
|
2598
2599
|
|
|
2599
2600
|
|
|
2601
|
+
|
|
2600
2602
|
|
|
2601
2603
|
|
|
2602
2604
|
static parse(plain ) {
|
|
@@ -2608,6 +2610,7 @@ class Meeting {
|
|
|
2608
2610
|
port: plain.port,
|
|
2609
2611
|
uuid: plain.uuid,
|
|
2610
2612
|
number: plain.number,
|
|
2613
|
+
persistent: plain.persistent,
|
|
2611
2614
|
});
|
|
2612
2615
|
}
|
|
2613
2616
|
|
|
@@ -2615,7 +2618,7 @@ class Meeting {
|
|
|
2615
2618
|
return newFrom(meeting, Meeting);
|
|
2616
2619
|
}
|
|
2617
2620
|
|
|
2618
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
2621
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
2619
2622
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2620
2623
|
this.uri = uri;
|
|
2621
2624
|
this.name = name;
|
|
@@ -2623,6 +2626,7 @@ class Meeting {
|
|
|
2623
2626
|
this.port = port;
|
|
2624
2627
|
this.uuid = uuid;
|
|
2625
2628
|
this.number = number;
|
|
2629
|
+
this.persistent = persistent;
|
|
2626
2630
|
|
|
2627
2631
|
// Useful to compare instead of instanceof with minified code
|
|
2628
2632
|
this.type = 'Meeting';
|
|
@@ -3186,7 +3190,7 @@ class Recording {
|
|
|
3186
3190
|
|
|
3187
3191
|
|
|
3188
3192
|
|
|
3189
|
-
static parseMany(recordings
|
|
3193
|
+
static parseMany(recordings = []) {
|
|
3190
3194
|
return recordings.map(item => Recording.parse(item));
|
|
3191
3195
|
}
|
|
3192
3196
|
|
|
@@ -3312,7 +3316,7 @@ class CallLog {
|
|
|
3312
3316
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3313
3317
|
start: moment(plain.start).toDate(),
|
|
3314
3318
|
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3315
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3319
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3316
3320
|
});
|
|
3317
3321
|
}
|
|
3318
3322
|
|
|
@@ -400,7 +400,7 @@ class IssueReporter {
|
|
|
400
400
|
payload._retry = retry + 1;
|
|
401
401
|
}
|
|
402
402
|
|
|
403
|
-
this._sendDebugToGrafana(
|
|
403
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
404
404
|
}, 5000 + retry * 1000);
|
|
405
405
|
});
|
|
406
406
|
}
|
|
@@ -2603,7 +2603,8 @@ class ExternalApp {
|
|
|
2603
2603
|
|
|
2604
2604
|
|
|
2605
2605
|
|
|
2606
|
-
|
|
2606
|
+
|
|
2607
|
+
|
|
2607
2608
|
|
|
2608
2609
|
|
|
2609
2610
|
class Meeting {
|
|
@@ -2615,6 +2616,7 @@ class Meeting {
|
|
|
2615
2616
|
|
|
2616
2617
|
|
|
2617
2618
|
|
|
2619
|
+
|
|
2618
2620
|
|
|
2619
2621
|
|
|
2620
2622
|
static parse(plain ) {
|
|
@@ -2626,6 +2628,7 @@ class Meeting {
|
|
|
2626
2628
|
port: plain.port,
|
|
2627
2629
|
uuid: plain.uuid,
|
|
2628
2630
|
number: plain.number,
|
|
2631
|
+
persistent: plain.persistent,
|
|
2629
2632
|
});
|
|
2630
2633
|
}
|
|
2631
2634
|
|
|
@@ -2633,7 +2636,7 @@ class Meeting {
|
|
|
2633
2636
|
return newFrom(meeting, Meeting);
|
|
2634
2637
|
}
|
|
2635
2638
|
|
|
2636
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
2639
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
2637
2640
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2638
2641
|
this.uri = uri;
|
|
2639
2642
|
this.name = name;
|
|
@@ -2641,6 +2644,7 @@ class Meeting {
|
|
|
2641
2644
|
this.port = port;
|
|
2642
2645
|
this.uuid = uuid;
|
|
2643
2646
|
this.number = number;
|
|
2647
|
+
this.persistent = persistent;
|
|
2644
2648
|
|
|
2645
2649
|
// Useful to compare instead of instanceof with minified code
|
|
2646
2650
|
this.type = 'Meeting';
|
|
@@ -3230,7 +3234,7 @@ class Recording {
|
|
|
3230
3234
|
|
|
3231
3235
|
|
|
3232
3236
|
|
|
3233
|
-
static parseMany(recordings
|
|
3237
|
+
static parseMany(recordings = []) {
|
|
3234
3238
|
return recordings.map(item => Recording.parse(item));
|
|
3235
3239
|
}
|
|
3236
3240
|
|
|
@@ -3356,7 +3360,7 @@ class CallLog {
|
|
|
3356
3360
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3357
3361
|
start: moment(plain.start).toDate(),
|
|
3358
3362
|
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3359
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3363
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3360
3364
|
});
|
|
3361
3365
|
}
|
|
3362
3366
|
|
|
@@ -5871,6 +5875,7 @@ const ON_REINVITE = 'reinvite';
|
|
|
5871
5875
|
const ON_ERROR = 'onError';
|
|
5872
5876
|
const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
|
|
5873
5877
|
const ON_NETWORK_STATS = 'onNetworkStats';
|
|
5878
|
+
const ON_DISCONNECTED = 'onDisconnected';
|
|
5874
5879
|
class CanceledCallError extends Error {}
|
|
5875
5880
|
|
|
5876
5881
|
const MAX_REGISTER_TRIES = 10;
|
|
@@ -5944,6 +5949,7 @@ class WebRTCClient extends Emitter {
|
|
|
5944
5949
|
|
|
5945
5950
|
|
|
5946
5951
|
|
|
5952
|
+
|
|
5947
5953
|
|
|
5948
5954
|
static isAPrivateIp(ip ) {
|
|
5949
5955
|
const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
|
|
@@ -6009,6 +6015,7 @@ class WebRTCClient extends Emitter {
|
|
|
6009
6015
|
this.ON_ERROR = ON_ERROR;
|
|
6010
6016
|
this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
|
|
6011
6017
|
this.ON_NETWORK_STATS = ON_NETWORK_STATS;
|
|
6018
|
+
this.ON_DISCONNECTED = ON_DISCONNECTED;
|
|
6012
6019
|
}
|
|
6013
6020
|
|
|
6014
6021
|
configureMedia(media ) {
|
|
@@ -6610,7 +6617,7 @@ class WebRTCClient extends Emitter {
|
|
|
6610
6617
|
// We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
|
|
6611
6618
|
const transceivers = pc.getTransceivers();
|
|
6612
6619
|
const transceiverIdx = lastIndexOf(transceivers, transceiver =>
|
|
6613
|
-
transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
|
|
6620
|
+
transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
|
|
6614
6621
|
|
|
6615
6622
|
videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
|
|
6616
6623
|
} else {
|
|
@@ -6856,10 +6863,13 @@ class WebRTCClient extends Emitter {
|
|
|
6856
6863
|
return null;
|
|
6857
6864
|
}
|
|
6858
6865
|
|
|
6859
|
-
// let's update the local value
|
|
6860
|
-
if (this.audio
|
|
6861
|
-
|
|
6862
|
-
|
|
6866
|
+
// let's update the local audio value
|
|
6867
|
+
if (this.audio) {
|
|
6868
|
+
this.audio = {
|
|
6869
|
+
deviceId: {
|
|
6870
|
+
exact: id,
|
|
6871
|
+
},
|
|
6872
|
+
};
|
|
6863
6873
|
}
|
|
6864
6874
|
|
|
6865
6875
|
if (session) {
|
|
@@ -6872,6 +6882,9 @@ class WebRTCClient extends Emitter {
|
|
|
6872
6882
|
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
6873
6883
|
|
|
6874
6884
|
if (sender) {
|
|
6885
|
+
if (sender.track) {
|
|
6886
|
+
audioTrack.enabled = sender.track.enabled;
|
|
6887
|
+
}
|
|
6875
6888
|
sender.replaceTrack(audioTrack);
|
|
6876
6889
|
}
|
|
6877
6890
|
|
|
@@ -6896,7 +6909,7 @@ class WebRTCClient extends Emitter {
|
|
|
6896
6909
|
return null;
|
|
6897
6910
|
}
|
|
6898
6911
|
|
|
6899
|
-
// let's update the local value
|
|
6912
|
+
// let's update the local video value
|
|
6900
6913
|
if (this.video) {
|
|
6901
6914
|
this.video = {
|
|
6902
6915
|
deviceId: {
|
|
@@ -6931,12 +6944,21 @@ class WebRTCClient extends Emitter {
|
|
|
6931
6944
|
return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
|
|
6932
6945
|
const videoTrack = stream.getVideoTracks()[0];
|
|
6933
6946
|
let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
|
|
6947
|
+
let wasTrackEnabled = false;
|
|
6934
6948
|
if (!sender) {
|
|
6935
6949
|
sender = pc && pc.getSenders().find(s => !s.track);
|
|
6936
6950
|
}
|
|
6937
6951
|
|
|
6938
6952
|
if (sender) {
|
|
6939
|
-
|
|
6953
|
+
// No video track means video not enabled
|
|
6954
|
+
wasTrackEnabled = sender.track ? sender.track.enabled : false;
|
|
6955
|
+
videoTrack.enabled = wasTrackEnabled;
|
|
6956
|
+
|
|
6957
|
+
if (!wasTrackEnabled) {
|
|
6958
|
+
videoTrack.stop();
|
|
6959
|
+
}
|
|
6960
|
+
|
|
6961
|
+
sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
|
|
6940
6962
|
}
|
|
6941
6963
|
|
|
6942
6964
|
// let's update the local stream
|
|
@@ -7620,6 +7642,7 @@ class WebRTCClient extends Emitter {
|
|
|
7620
7642
|
|
|
7621
7643
|
this.updateRemoteStream(this.getSipSessionId(session));
|
|
7622
7644
|
|
|
7645
|
+
const pc = session.sessionDescriptionHandler.peerConnection;
|
|
7623
7646
|
const onTrack = (event ) => {
|
|
7624
7647
|
const isAudioOnly = this._isAudioOnly(session);
|
|
7625
7648
|
const { kind, label, readyState, id, muted } = event.track;
|
|
@@ -7639,6 +7662,12 @@ class WebRTCClient extends Emitter {
|
|
|
7639
7662
|
|
|
7640
7663
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
7641
7664
|
|
|
7665
|
+
pc.oniceconnectionstatechange = () => {
|
|
7666
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
7667
|
+
this.eventEmitter.emit(ON_DISCONNECTED);
|
|
7668
|
+
}
|
|
7669
|
+
};
|
|
7670
|
+
|
|
7642
7671
|
if (withEvent) {
|
|
7643
7672
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
7644
7673
|
}
|
|
@@ -7850,25 +7879,33 @@ class WebRTCClient extends Emitter {
|
|
|
7850
7879
|
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
7851
7880
|
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
7852
7881
|
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
7882
|
+
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
7883
|
+
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
7853
7884
|
let audioBytesSent = 0;
|
|
7854
7885
|
let audioBytesReceived = 0;
|
|
7855
7886
|
let videoBytesSent = 0;
|
|
7856
7887
|
let videoBytesReceived = 0;
|
|
7888
|
+
let transportSent = 0;
|
|
7889
|
+
let transportReceived = 0;
|
|
7890
|
+
let packetsLost = 0;
|
|
7857
7891
|
|
|
7858
7892
|
stats.forEach(report => {
|
|
7859
7893
|
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
7894
|
+
audioBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7895
|
+
}
|
|
7896
|
+
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
7860
7897
|
audioBytesSent += report.bytesSent;
|
|
7861
7898
|
}
|
|
7862
7899
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7863
|
-
videoBytesSent += report.bytesSent;
|
|
7900
|
+
videoBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7864
7901
|
}
|
|
7865
7902
|
if (report.type === 'inbound-rtp' && report.kind === 'audio') {
|
|
7866
|
-
|
|
7903
|
+
packetsLost += report.packetsLost;
|
|
7867
7904
|
networkStats.packetsReceived = report.packetsReceived;
|
|
7868
|
-
audioBytesReceived += report.bytesReceived;
|
|
7905
|
+
audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7869
7906
|
}
|
|
7870
7907
|
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
7871
|
-
videoBytesReceived += report.bytesReceived;
|
|
7908
|
+
videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7872
7909
|
}
|
|
7873
7910
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7874
7911
|
if ('framesPerSecond' in report) {
|
|
@@ -7880,19 +7917,32 @@ class WebRTCClient extends Emitter {
|
|
|
7880
7917
|
}
|
|
7881
7918
|
}
|
|
7882
7919
|
if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
|
|
7920
|
+
packetsLost += report.packetsLost;
|
|
7883
7921
|
networkStats.roundTripTime = report.roundTripTime;
|
|
7884
7922
|
networkStats.jitter = report.jitter;
|
|
7885
7923
|
}
|
|
7924
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
|
|
7925
|
+
packetsLost += report.packetsLost;
|
|
7926
|
+
}
|
|
7927
|
+
if (report.type === 'transport') {
|
|
7928
|
+
transportSent += report.bytesSent;
|
|
7929
|
+
transportReceived += report.bytesReceived;
|
|
7930
|
+
}
|
|
7886
7931
|
});
|
|
7887
7932
|
|
|
7933
|
+
networkStats.packetsLost = packetsLost;
|
|
7888
7934
|
networkStats.audioBytesSent = audioBytesSent;
|
|
7889
7935
|
networkStats.audioBytesReceived = audioBytesReceived;
|
|
7890
7936
|
networkStats.videoBytesSent = videoBytesSent;
|
|
7891
7937
|
networkStats.videoBytesReceived = videoBytesReceived;
|
|
7938
|
+
networkStats.transportSent = transportSent;
|
|
7939
|
+
networkStats.transportReceived = transportReceived;
|
|
7940
|
+
|
|
7941
|
+
const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
|
|
7942
|
+
+ (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
|
|
7943
|
+
+ (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
|
|
7892
7944
|
|
|
7893
|
-
networkStats.bandwidth =
|
|
7894
|
-
+ (networkStats.videoBytesSent - lastVideoSent) + (networkStats.audioBytesReceived - lastAudioReceived)
|
|
7895
|
-
+ (networkStats.videoBytesReceived - lastVideoReceived);
|
|
7945
|
+
networkStats.bandwidth = bandwidth;
|
|
7896
7946
|
|
|
7897
7947
|
this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
|
|
7898
7948
|
this.sessionNetworkStats[sessionId].push(networkStats);
|