@wazo/sdk 0.37.15 → 0.37.19
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 +3 -3
- package/esm/__tests__/api-client.test.js +9 -5
- package/esm/__tests__/web-rtc-client.test.js +117 -23
- 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 +117 -23
- package/esm/checker/checks/aor.js +9 -5
- package/esm/checker/checks/api.js +9 -5
- package/esm/checker/checks/index.js +117 -23
- package/esm/checker/checks/wazo-websocket.js +1 -1
- package/esm/checker/checks/webrtc-transport.js +117 -23
- package/esm/checker/checks/webrtc.js +117 -23
- 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 +125 -23
- 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 +125 -23
- package/esm/simple/Configuration.js +125 -23
- package/esm/simple/Directory.js +9 -5
- package/esm/simple/Phone.js +125 -23
- package/esm/simple/Websocket.js +1 -1
- package/esm/simple/index.js +125 -23
- package/esm/simple/room/LocalParticipant.js +125 -23
- package/esm/simple/room/Participant.js +125 -23
- package/esm/simple/room/RemoteParticipant.js +125 -23
- package/esm/simple/room/Room.js +125 -23
- package/esm/simple/room/SipRoom.js +125 -23
- package/esm/simple/room/Stream.js +125 -23
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +125 -23
- package/esm/simple/utils.js +125 -23
- package/esm/utils/__tests__/api-requester.test.js +1 -1
- package/esm/utils/api-requester.js +1 -1
- package/esm/web-rtc-client.js +117 -23
- package/esm/websocket-client.js +1 -1
- package/lib/__tests__/api-client.test.js +9 -5
- package/lib/__tests__/web-rtc-client.test.js +117 -23
- 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 +117 -23
- package/lib/checker/checks/aor.js +9 -5
- package/lib/checker/checks/api.js +9 -5
- package/lib/checker/checks/index.js +117 -23
- package/lib/checker/checks/wazo-websocket.js +1 -1
- package/lib/checker/checks/webrtc-transport.js +117 -23
- package/lib/checker/checks/webrtc.js +117 -23
- 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 +125 -23
- 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 +125 -23
- package/lib/simple/Configuration.js +125 -23
- package/lib/simple/Directory.js +9 -5
- package/lib/simple/Phone.js +125 -23
- package/lib/simple/Websocket.js +1 -1
- package/lib/simple/index.js +125 -23
- package/lib/simple/room/LocalParticipant.js +125 -23
- package/lib/simple/room/Participant.js +125 -23
- package/lib/simple/room/RemoteParticipant.js +125 -23
- package/lib/simple/room/Room.js +125 -23
- package/lib/simple/room/SipRoom.js +125 -23
- package/lib/simple/room/Stream.js +125 -23
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +125 -23
- package/lib/simple/utils.js +125 -23
- package/lib/utils/__tests__/api-requester.test.js +1 -1
- package/lib/utils/api-requester.js +1 -1
- package/lib/web-rtc-client.js +117 -23
- package/lib/websocket-client.js +1 -1
- package/package.json +1 -1
- 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 +108 -18
package/esm/simple/utils.js
CHANGED
|
@@ -1886,7 +1886,7 @@ class IssueReporter {
|
|
|
1886
1886
|
payload._retry = retry + 1;
|
|
1887
1887
|
}
|
|
1888
1888
|
|
|
1889
|
-
this._sendDebugToGrafana(
|
|
1889
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
1890
1890
|
}, 5000 + retry * 1000);
|
|
1891
1891
|
});
|
|
1892
1892
|
}
|
|
@@ -2604,7 +2604,8 @@ class ExternalApp {
|
|
|
2604
2604
|
|
|
2605
2605
|
|
|
2606
2606
|
|
|
2607
|
-
|
|
2607
|
+
|
|
2608
|
+
|
|
2608
2609
|
|
|
2609
2610
|
|
|
2610
2611
|
class Meeting {
|
|
@@ -2616,6 +2617,7 @@ class Meeting {
|
|
|
2616
2617
|
|
|
2617
2618
|
|
|
2618
2619
|
|
|
2620
|
+
|
|
2619
2621
|
|
|
2620
2622
|
|
|
2621
2623
|
static parse(plain ) {
|
|
@@ -2627,6 +2629,7 @@ class Meeting {
|
|
|
2627
2629
|
port: plain.port,
|
|
2628
2630
|
uuid: plain.uuid,
|
|
2629
2631
|
number: plain.number,
|
|
2632
|
+
persistent: plain.persistent,
|
|
2630
2633
|
});
|
|
2631
2634
|
}
|
|
2632
2635
|
|
|
@@ -2634,7 +2637,7 @@ class Meeting {
|
|
|
2634
2637
|
return newFrom(meeting, Meeting);
|
|
2635
2638
|
}
|
|
2636
2639
|
|
|
2637
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
2640
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
2638
2641
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2639
2642
|
this.uri = uri;
|
|
2640
2643
|
this.name = name;
|
|
@@ -2642,6 +2645,7 @@ class Meeting {
|
|
|
2642
2645
|
this.port = port;
|
|
2643
2646
|
this.uuid = uuid;
|
|
2644
2647
|
this.number = number;
|
|
2648
|
+
this.persistent = persistent;
|
|
2645
2649
|
|
|
2646
2650
|
// Useful to compare instead of instanceof with minified code
|
|
2647
2651
|
this.type = 'Meeting';
|
|
@@ -3576,7 +3580,7 @@ class Recording {
|
|
|
3576
3580
|
|
|
3577
3581
|
|
|
3578
3582
|
|
|
3579
|
-
static parseMany(recordings
|
|
3583
|
+
static parseMany(recordings = []) {
|
|
3580
3584
|
return recordings.map(item => Recording.parse(item));
|
|
3581
3585
|
}
|
|
3582
3586
|
|
|
@@ -3702,7 +3706,7 @@ class CallLog {
|
|
|
3702
3706
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3703
3707
|
start: moment(plain.start).toDate(),
|
|
3704
3708
|
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3705
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3709
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3706
3710
|
});
|
|
3707
3711
|
}
|
|
3708
3712
|
|
|
@@ -6547,6 +6551,7 @@ const ON_REINVITE$1 = 'reinvite';
|
|
|
6547
6551
|
const ON_ERROR = 'onError';
|
|
6548
6552
|
const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
|
|
6549
6553
|
const ON_NETWORK_STATS$1 = 'onNetworkStats';
|
|
6554
|
+
const ON_DISCONNECTED$1 = 'onDisconnected';
|
|
6550
6555
|
|
|
6551
6556
|
const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
6552
6557
|
const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
|
|
@@ -6623,6 +6628,7 @@ class WebRTCClient extends Emitter {
|
|
|
6623
6628
|
|
|
6624
6629
|
|
|
6625
6630
|
|
|
6631
|
+
|
|
6626
6632
|
|
|
6627
6633
|
static isAPrivateIp(ip ) {
|
|
6628
6634
|
const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
|
|
@@ -6688,6 +6694,7 @@ class WebRTCClient extends Emitter {
|
|
|
6688
6694
|
this.ON_ERROR = ON_ERROR;
|
|
6689
6695
|
this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
|
|
6690
6696
|
this.ON_NETWORK_STATS = ON_NETWORK_STATS$1;
|
|
6697
|
+
this.ON_DISCONNECTED = ON_DISCONNECTED$1;
|
|
6691
6698
|
}
|
|
6692
6699
|
|
|
6693
6700
|
configureMedia(media ) {
|
|
@@ -7289,7 +7296,7 @@ class WebRTCClient extends Emitter {
|
|
|
7289
7296
|
// We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
|
|
7290
7297
|
const transceivers = pc.getTransceivers();
|
|
7291
7298
|
const transceiverIdx = lastIndexOf(transceivers, transceiver =>
|
|
7292
|
-
transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
|
|
7299
|
+
transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
|
|
7293
7300
|
|
|
7294
7301
|
videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
|
|
7295
7302
|
} else {
|
|
@@ -7535,10 +7542,13 @@ class WebRTCClient extends Emitter {
|
|
|
7535
7542
|
return null;
|
|
7536
7543
|
}
|
|
7537
7544
|
|
|
7538
|
-
// let's update the local value
|
|
7539
|
-
if (this.audio
|
|
7540
|
-
|
|
7541
|
-
|
|
7545
|
+
// let's update the local audio value
|
|
7546
|
+
if (this.audio) {
|
|
7547
|
+
this.audio = {
|
|
7548
|
+
deviceId: {
|
|
7549
|
+
exact: id,
|
|
7550
|
+
},
|
|
7551
|
+
};
|
|
7542
7552
|
}
|
|
7543
7553
|
|
|
7544
7554
|
if (session) {
|
|
@@ -7551,6 +7561,9 @@ class WebRTCClient extends Emitter {
|
|
|
7551
7561
|
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
7552
7562
|
|
|
7553
7563
|
if (sender) {
|
|
7564
|
+
if (sender.track) {
|
|
7565
|
+
audioTrack.enabled = sender.track.enabled;
|
|
7566
|
+
}
|
|
7554
7567
|
sender.replaceTrack(audioTrack);
|
|
7555
7568
|
}
|
|
7556
7569
|
|
|
@@ -7575,7 +7588,7 @@ class WebRTCClient extends Emitter {
|
|
|
7575
7588
|
return null;
|
|
7576
7589
|
}
|
|
7577
7590
|
|
|
7578
|
-
// let's update the local value
|
|
7591
|
+
// let's update the local video value
|
|
7579
7592
|
if (this.video) {
|
|
7580
7593
|
this.video = {
|
|
7581
7594
|
deviceId: {
|
|
@@ -7610,12 +7623,21 @@ class WebRTCClient extends Emitter {
|
|
|
7610
7623
|
return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
|
|
7611
7624
|
const videoTrack = stream.getVideoTracks()[0];
|
|
7612
7625
|
let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
|
|
7626
|
+
let wasTrackEnabled = false;
|
|
7613
7627
|
if (!sender) {
|
|
7614
7628
|
sender = pc && pc.getSenders().find(s => !s.track);
|
|
7615
7629
|
}
|
|
7616
7630
|
|
|
7617
7631
|
if (sender) {
|
|
7618
|
-
|
|
7632
|
+
// No video track means video not enabled
|
|
7633
|
+
wasTrackEnabled = sender.track ? sender.track.enabled : false;
|
|
7634
|
+
videoTrack.enabled = wasTrackEnabled;
|
|
7635
|
+
|
|
7636
|
+
if (!wasTrackEnabled) {
|
|
7637
|
+
videoTrack.stop();
|
|
7638
|
+
}
|
|
7639
|
+
|
|
7640
|
+
sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
|
|
7619
7641
|
}
|
|
7620
7642
|
|
|
7621
7643
|
// let's update the local stream
|
|
@@ -8299,6 +8321,7 @@ class WebRTCClient extends Emitter {
|
|
|
8299
8321
|
|
|
8300
8322
|
this.updateRemoteStream(this.getSipSessionId(session));
|
|
8301
8323
|
|
|
8324
|
+
const pc = session.sessionDescriptionHandler.peerConnection;
|
|
8302
8325
|
const onTrack = (event ) => {
|
|
8303
8326
|
const isAudioOnly = this._isAudioOnly(session);
|
|
8304
8327
|
const { kind, label, readyState, id, muted } = event.track;
|
|
@@ -8318,6 +8341,12 @@ class WebRTCClient extends Emitter {
|
|
|
8318
8341
|
|
|
8319
8342
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
8320
8343
|
|
|
8344
|
+
pc.oniceconnectionstatechange = () => {
|
|
8345
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
8346
|
+
this.eventEmitter.emit(ON_DISCONNECTED$1);
|
|
8347
|
+
}
|
|
8348
|
+
};
|
|
8349
|
+
|
|
8321
8350
|
if (withEvent) {
|
|
8322
8351
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
8323
8352
|
}
|
|
@@ -8513,24 +8542,89 @@ class WebRTCClient extends Emitter {
|
|
|
8513
8542
|
const session = this.getSipSession(sessionId);
|
|
8514
8543
|
|
|
8515
8544
|
const stats = session ? await this.getStats(session) : null;
|
|
8516
|
-
if (!stats) {
|
|
8545
|
+
if (!stats || !(sessionId in this.sessionNetworkStats)) {
|
|
8517
8546
|
return;
|
|
8518
8547
|
}
|
|
8519
8548
|
|
|
8520
|
-
|
|
8521
|
-
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8549
|
+
const networkStats = {
|
|
8550
|
+
audioBytesSent: 0,
|
|
8551
|
+
videoBytesSent: 0,
|
|
8552
|
+
videoBytesReceived: 0,
|
|
8553
|
+
audioBytesReceived: 0,
|
|
8554
|
+
};
|
|
8555
|
+
const nbStats = this.sessionNetworkStats[sessionId].length;
|
|
8556
|
+
const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
|
|
8557
|
+
const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
|
|
8558
|
+
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
8559
|
+
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
8560
|
+
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
8561
|
+
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
8562
|
+
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
8563
|
+
let audioBytesSent = 0;
|
|
8564
|
+
let audioBytesReceived = 0;
|
|
8565
|
+
let videoBytesSent = 0;
|
|
8566
|
+
let videoBytesReceived = 0;
|
|
8567
|
+
let transportSent = 0;
|
|
8568
|
+
let transportReceived = 0;
|
|
8569
|
+
let packetsLost = 0;
|
|
8528
8570
|
|
|
8529
|
-
|
|
8530
|
-
|
|
8571
|
+
stats.forEach(report => {
|
|
8572
|
+
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
8573
|
+
audioBytesSent += report.bytesSent + report.headerBytesSent;
|
|
8574
|
+
}
|
|
8575
|
+
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
8576
|
+
audioBytesSent += report.bytesSent;
|
|
8577
|
+
}
|
|
8578
|
+
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
8579
|
+
videoBytesSent += report.bytesSent + report.headerBytesSent;
|
|
8580
|
+
}
|
|
8581
|
+
if (report.type === 'inbound-rtp' && report.kind === 'audio') {
|
|
8582
|
+
packetsLost += report.packetsLost;
|
|
8583
|
+
networkStats.packetsReceived = report.packetsReceived;
|
|
8584
|
+
audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
8585
|
+
}
|
|
8586
|
+
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
8587
|
+
videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
8588
|
+
}
|
|
8589
|
+
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
8590
|
+
if ('framesPerSecond' in report) {
|
|
8591
|
+
networkStats.framesPerSecond = report.framesPerSecond;
|
|
8592
|
+
}
|
|
8593
|
+
if ('framerateMean' in report) {
|
|
8594
|
+
// framerateMean is only available in FF
|
|
8595
|
+
networkStats.framesPerSecond = Math.round(report.framerateMean);
|
|
8531
8596
|
}
|
|
8532
8597
|
}
|
|
8598
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
|
|
8599
|
+
packetsLost += report.packetsLost;
|
|
8600
|
+
networkStats.roundTripTime = report.roundTripTime;
|
|
8601
|
+
networkStats.jitter = report.jitter;
|
|
8602
|
+
}
|
|
8603
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
|
|
8604
|
+
packetsLost += report.packetsLost;
|
|
8605
|
+
}
|
|
8606
|
+
if (report.type === 'transport') {
|
|
8607
|
+
transportSent += report.bytesSent;
|
|
8608
|
+
transportReceived += report.bytesReceived;
|
|
8609
|
+
}
|
|
8533
8610
|
});
|
|
8611
|
+
|
|
8612
|
+
networkStats.packetsLost = packetsLost;
|
|
8613
|
+
networkStats.audioBytesSent = audioBytesSent;
|
|
8614
|
+
networkStats.audioBytesReceived = audioBytesReceived;
|
|
8615
|
+
networkStats.videoBytesSent = videoBytesSent;
|
|
8616
|
+
networkStats.videoBytesReceived = videoBytesReceived;
|
|
8617
|
+
networkStats.transportSent = transportSent;
|
|
8618
|
+
networkStats.transportReceived = transportReceived;
|
|
8619
|
+
|
|
8620
|
+
const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
|
|
8621
|
+
+ (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
|
|
8622
|
+
+ (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
|
|
8623
|
+
|
|
8624
|
+
networkStats.bandwidth = bandwidth;
|
|
8625
|
+
|
|
8626
|
+
this.eventEmitter.emit(ON_NETWORK_STATS$1, session, networkStats, this.sessionNetworkStats[sessionId]);
|
|
8627
|
+
this.sessionNetworkStats[sessionId].push(networkStats);
|
|
8534
8628
|
}
|
|
8535
8629
|
|
|
8536
8630
|
}
|
|
@@ -8576,6 +8670,7 @@ const ON_MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
|
|
|
8576
8670
|
const ON_NETWORK_STATS = 'onNetworkStats';
|
|
8577
8671
|
const ON_CHAT = 'phone/ON_CHAT';
|
|
8578
8672
|
const ON_SIGNAL = 'phone/ON_SIGNAL';
|
|
8673
|
+
const ON_DISCONNECTED = 'onDisconnected';
|
|
8579
8674
|
|
|
8580
8675
|
const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
|
|
8581
8676
|
const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
|
|
@@ -8615,6 +8710,7 @@ const events = [
|
|
|
8615
8710
|
ON_CHAT,
|
|
8616
8711
|
ON_SIGNAL,
|
|
8617
8712
|
ON_NETWORK_STATS,
|
|
8713
|
+
ON_DISCONNECTED,
|
|
8618
8714
|
];
|
|
8619
8715
|
|
|
8620
8716
|
const logger$7 = IssueReporter$1.loggerFor('webrtc-phone');
|
|
@@ -9967,6 +10063,11 @@ class WebRTCPhone extends Emitter {
|
|
|
9967
10063
|
this.eventEmitter.emit(ON_UNREGISTERED);
|
|
9968
10064
|
});
|
|
9969
10065
|
|
|
10066
|
+
this.client.on(this.client.ON_DISCONNECTED, () => {
|
|
10067
|
+
logger$7.info('WebRTC disconnected');
|
|
10068
|
+
this.eventEmitter.emit(ON_DISCONNECTED);
|
|
10069
|
+
});
|
|
10070
|
+
|
|
9970
10071
|
this.client.on(this.client.REGISTERED, () => {
|
|
9971
10072
|
logger$7.info('WebRTC registered', {
|
|
9972
10073
|
shouldSendReinvite: this.shouldSendReinvite,
|
|
@@ -10223,6 +10324,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
|
|
|
10223
10324
|
ON_NETWORK_STATS: ON_NETWORK_STATS,
|
|
10224
10325
|
ON_CHAT: ON_CHAT,
|
|
10225
10326
|
ON_SIGNAL: ON_SIGNAL,
|
|
10327
|
+
ON_DISCONNECTED: ON_DISCONNECTED,
|
|
10226
10328
|
MESSAGE_TYPE_CHAT: MESSAGE_TYPE_CHAT,
|
|
10227
10329
|
MESSAGE_TYPE_SIGNAL: MESSAGE_TYPE_SIGNAL,
|
|
10228
10330
|
events: events,
|
package/esm/web-rtc-client.js
CHANGED
|
@@ -664,7 +664,7 @@ class IssueReporter {
|
|
|
664
664
|
payload._retry = retry + 1;
|
|
665
665
|
}
|
|
666
666
|
|
|
667
|
-
this._sendDebugToGrafana(
|
|
667
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
668
668
|
}, 5000 + retry * 1000);
|
|
669
669
|
});
|
|
670
670
|
}
|
|
@@ -3166,7 +3166,8 @@ class ExternalApp {
|
|
|
3166
3166
|
|
|
3167
3167
|
|
|
3168
3168
|
|
|
3169
|
-
|
|
3169
|
+
|
|
3170
|
+
|
|
3170
3171
|
|
|
3171
3172
|
|
|
3172
3173
|
class Meeting {
|
|
@@ -3178,6 +3179,7 @@ class Meeting {
|
|
|
3178
3179
|
|
|
3179
3180
|
|
|
3180
3181
|
|
|
3182
|
+
|
|
3181
3183
|
|
|
3182
3184
|
|
|
3183
3185
|
static parse(plain ) {
|
|
@@ -3189,6 +3191,7 @@ class Meeting {
|
|
|
3189
3191
|
port: plain.port,
|
|
3190
3192
|
uuid: plain.uuid,
|
|
3191
3193
|
number: plain.number,
|
|
3194
|
+
persistent: plain.persistent,
|
|
3192
3195
|
});
|
|
3193
3196
|
}
|
|
3194
3197
|
|
|
@@ -3196,7 +3199,7 @@ class Meeting {
|
|
|
3196
3199
|
return newFrom(meeting, Meeting);
|
|
3197
3200
|
}
|
|
3198
3201
|
|
|
3199
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
3202
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
3200
3203
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
3201
3204
|
this.uri = uri;
|
|
3202
3205
|
this.name = name;
|
|
@@ -3204,6 +3207,7 @@ class Meeting {
|
|
|
3204
3207
|
this.port = port;
|
|
3205
3208
|
this.uuid = uuid;
|
|
3206
3209
|
this.number = number;
|
|
3210
|
+
this.persistent = persistent;
|
|
3207
3211
|
|
|
3208
3212
|
// Useful to compare instead of instanceof with minified code
|
|
3209
3213
|
this.type = 'Meeting';
|
|
@@ -3767,7 +3771,7 @@ class Recording {
|
|
|
3767
3771
|
|
|
3768
3772
|
|
|
3769
3773
|
|
|
3770
|
-
static parseMany(recordings
|
|
3774
|
+
static parseMany(recordings = []) {
|
|
3771
3775
|
return recordings.map(item => Recording.parse(item));
|
|
3772
3776
|
}
|
|
3773
3777
|
|
|
@@ -3893,7 +3897,7 @@ class CallLog {
|
|
|
3893
3897
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3894
3898
|
start: moment(plain.start).toDate(),
|
|
3895
3899
|
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3896
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3900
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3897
3901
|
});
|
|
3898
3902
|
}
|
|
3899
3903
|
|
|
@@ -5288,6 +5292,7 @@ const ON_REINVITE = 'reinvite';
|
|
|
5288
5292
|
const ON_ERROR = 'onError';
|
|
5289
5293
|
const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
|
|
5290
5294
|
const ON_NETWORK_STATS = 'onNetworkStats';
|
|
5295
|
+
const ON_DISCONNECTED = 'onDisconnected';
|
|
5291
5296
|
|
|
5292
5297
|
const events = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
5293
5298
|
const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
|
|
@@ -5364,6 +5369,7 @@ class WebRTCClient extends Emitter {
|
|
|
5364
5369
|
|
|
5365
5370
|
|
|
5366
5371
|
|
|
5372
|
+
|
|
5367
5373
|
|
|
5368
5374
|
static isAPrivateIp(ip ) {
|
|
5369
5375
|
const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
|
|
@@ -5429,6 +5435,7 @@ class WebRTCClient extends Emitter {
|
|
|
5429
5435
|
this.ON_ERROR = ON_ERROR;
|
|
5430
5436
|
this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
|
|
5431
5437
|
this.ON_NETWORK_STATS = ON_NETWORK_STATS;
|
|
5438
|
+
this.ON_DISCONNECTED = ON_DISCONNECTED;
|
|
5432
5439
|
}
|
|
5433
5440
|
|
|
5434
5441
|
configureMedia(media ) {
|
|
@@ -6030,7 +6037,7 @@ class WebRTCClient extends Emitter {
|
|
|
6030
6037
|
// We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
|
|
6031
6038
|
const transceivers = pc.getTransceivers();
|
|
6032
6039
|
const transceiverIdx = lastIndexOf(transceivers, transceiver =>
|
|
6033
|
-
transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
|
|
6040
|
+
transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
|
|
6034
6041
|
|
|
6035
6042
|
videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
|
|
6036
6043
|
} else {
|
|
@@ -6276,10 +6283,13 @@ class WebRTCClient extends Emitter {
|
|
|
6276
6283
|
return null;
|
|
6277
6284
|
}
|
|
6278
6285
|
|
|
6279
|
-
// let's update the local value
|
|
6280
|
-
if (this.audio
|
|
6281
|
-
|
|
6282
|
-
|
|
6286
|
+
// let's update the local audio value
|
|
6287
|
+
if (this.audio) {
|
|
6288
|
+
this.audio = {
|
|
6289
|
+
deviceId: {
|
|
6290
|
+
exact: id,
|
|
6291
|
+
},
|
|
6292
|
+
};
|
|
6283
6293
|
}
|
|
6284
6294
|
|
|
6285
6295
|
if (session) {
|
|
@@ -6292,6 +6302,9 @@ class WebRTCClient extends Emitter {
|
|
|
6292
6302
|
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
6293
6303
|
|
|
6294
6304
|
if (sender) {
|
|
6305
|
+
if (sender.track) {
|
|
6306
|
+
audioTrack.enabled = sender.track.enabled;
|
|
6307
|
+
}
|
|
6295
6308
|
sender.replaceTrack(audioTrack);
|
|
6296
6309
|
}
|
|
6297
6310
|
|
|
@@ -6316,7 +6329,7 @@ class WebRTCClient extends Emitter {
|
|
|
6316
6329
|
return null;
|
|
6317
6330
|
}
|
|
6318
6331
|
|
|
6319
|
-
// let's update the local value
|
|
6332
|
+
// let's update the local video value
|
|
6320
6333
|
if (this.video) {
|
|
6321
6334
|
this.video = {
|
|
6322
6335
|
deviceId: {
|
|
@@ -6351,12 +6364,21 @@ class WebRTCClient extends Emitter {
|
|
|
6351
6364
|
return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
|
|
6352
6365
|
const videoTrack = stream.getVideoTracks()[0];
|
|
6353
6366
|
let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
|
|
6367
|
+
let wasTrackEnabled = false;
|
|
6354
6368
|
if (!sender) {
|
|
6355
6369
|
sender = pc && pc.getSenders().find(s => !s.track);
|
|
6356
6370
|
}
|
|
6357
6371
|
|
|
6358
6372
|
if (sender) {
|
|
6359
|
-
|
|
6373
|
+
// No video track means video not enabled
|
|
6374
|
+
wasTrackEnabled = sender.track ? sender.track.enabled : false;
|
|
6375
|
+
videoTrack.enabled = wasTrackEnabled;
|
|
6376
|
+
|
|
6377
|
+
if (!wasTrackEnabled) {
|
|
6378
|
+
videoTrack.stop();
|
|
6379
|
+
}
|
|
6380
|
+
|
|
6381
|
+
sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
|
|
6360
6382
|
}
|
|
6361
6383
|
|
|
6362
6384
|
// let's update the local stream
|
|
@@ -7040,6 +7062,7 @@ class WebRTCClient extends Emitter {
|
|
|
7040
7062
|
|
|
7041
7063
|
this.updateRemoteStream(this.getSipSessionId(session));
|
|
7042
7064
|
|
|
7065
|
+
const pc = session.sessionDescriptionHandler.peerConnection;
|
|
7043
7066
|
const onTrack = (event ) => {
|
|
7044
7067
|
const isAudioOnly = this._isAudioOnly(session);
|
|
7045
7068
|
const { kind, label, readyState, id, muted } = event.track;
|
|
@@ -7059,6 +7082,12 @@ class WebRTCClient extends Emitter {
|
|
|
7059
7082
|
|
|
7060
7083
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
7061
7084
|
|
|
7085
|
+
pc.oniceconnectionstatechange = () => {
|
|
7086
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
7087
|
+
this.eventEmitter.emit(ON_DISCONNECTED);
|
|
7088
|
+
}
|
|
7089
|
+
};
|
|
7090
|
+
|
|
7062
7091
|
if (withEvent) {
|
|
7063
7092
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
7064
7093
|
}
|
|
@@ -7254,24 +7283,89 @@ class WebRTCClient extends Emitter {
|
|
|
7254
7283
|
const session = this.getSipSession(sessionId);
|
|
7255
7284
|
|
|
7256
7285
|
const stats = session ? await this.getStats(session) : null;
|
|
7257
|
-
if (!stats) {
|
|
7286
|
+
if (!stats || !(sessionId in this.sessionNetworkStats)) {
|
|
7258
7287
|
return;
|
|
7259
7288
|
}
|
|
7260
7289
|
|
|
7290
|
+
const networkStats = {
|
|
7291
|
+
audioBytesSent: 0,
|
|
7292
|
+
videoBytesSent: 0,
|
|
7293
|
+
videoBytesReceived: 0,
|
|
7294
|
+
audioBytesReceived: 0,
|
|
7295
|
+
};
|
|
7296
|
+
const nbStats = this.sessionNetworkStats[sessionId].length;
|
|
7297
|
+
const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
|
|
7298
|
+
const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
|
|
7299
|
+
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
7300
|
+
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
7301
|
+
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
7302
|
+
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
7303
|
+
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
7304
|
+
let audioBytesSent = 0;
|
|
7305
|
+
let audioBytesReceived = 0;
|
|
7306
|
+
let videoBytesSent = 0;
|
|
7307
|
+
let videoBytesReceived = 0;
|
|
7308
|
+
let transportSent = 0;
|
|
7309
|
+
let transportReceived = 0;
|
|
7310
|
+
let packetsLost = 0;
|
|
7311
|
+
|
|
7261
7312
|
stats.forEach(report => {
|
|
7262
|
-
if (report.type === '
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
|
|
7271
|
-
|
|
7313
|
+
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
7314
|
+
audioBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7315
|
+
}
|
|
7316
|
+
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
7317
|
+
audioBytesSent += report.bytesSent;
|
|
7318
|
+
}
|
|
7319
|
+
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7320
|
+
videoBytesSent += report.bytesSent + report.headerBytesSent;
|
|
7321
|
+
}
|
|
7322
|
+
if (report.type === 'inbound-rtp' && report.kind === 'audio') {
|
|
7323
|
+
packetsLost += report.packetsLost;
|
|
7324
|
+
networkStats.packetsReceived = report.packetsReceived;
|
|
7325
|
+
audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7326
|
+
}
|
|
7327
|
+
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
7328
|
+
videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
7329
|
+
}
|
|
7330
|
+
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
7331
|
+
if ('framesPerSecond' in report) {
|
|
7332
|
+
networkStats.framesPerSecond = report.framesPerSecond;
|
|
7272
7333
|
}
|
|
7334
|
+
if ('framerateMean' in report) {
|
|
7335
|
+
// framerateMean is only available in FF
|
|
7336
|
+
networkStats.framesPerSecond = Math.round(report.framerateMean);
|
|
7337
|
+
}
|
|
7338
|
+
}
|
|
7339
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
|
|
7340
|
+
packetsLost += report.packetsLost;
|
|
7341
|
+
networkStats.roundTripTime = report.roundTripTime;
|
|
7342
|
+
networkStats.jitter = report.jitter;
|
|
7343
|
+
}
|
|
7344
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
|
|
7345
|
+
packetsLost += report.packetsLost;
|
|
7346
|
+
}
|
|
7347
|
+
if (report.type === 'transport') {
|
|
7348
|
+
transportSent += report.bytesSent;
|
|
7349
|
+
transportReceived += report.bytesReceived;
|
|
7273
7350
|
}
|
|
7274
7351
|
});
|
|
7352
|
+
|
|
7353
|
+
networkStats.packetsLost = packetsLost;
|
|
7354
|
+
networkStats.audioBytesSent = audioBytesSent;
|
|
7355
|
+
networkStats.audioBytesReceived = audioBytesReceived;
|
|
7356
|
+
networkStats.videoBytesSent = videoBytesSent;
|
|
7357
|
+
networkStats.videoBytesReceived = videoBytesReceived;
|
|
7358
|
+
networkStats.transportSent = transportSent;
|
|
7359
|
+
networkStats.transportReceived = transportReceived;
|
|
7360
|
+
|
|
7361
|
+
const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
|
|
7362
|
+
+ (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
|
|
7363
|
+
+ (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
|
|
7364
|
+
|
|
7365
|
+
networkStats.bandwidth = bandwidth;
|
|
7366
|
+
|
|
7367
|
+
this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
|
|
7368
|
+
this.sessionNetworkStats[sessionId].push(networkStats);
|
|
7275
7369
|
}
|
|
7276
7370
|
|
|
7277
7371
|
}
|
package/esm/websocket-client.js
CHANGED
|
@@ -388,7 +388,7 @@ class IssueReporter {
|
|
|
388
388
|
payload._retry = retry + 1;
|
|
389
389
|
}
|
|
390
390
|
|
|
391
|
-
this._sendDebugToGrafana(
|
|
391
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
392
392
|
}, 5000 + retry * 1000);
|
|
393
393
|
});
|
|
394
394
|
}
|
|
@@ -2591,7 +2591,8 @@ class ExternalApp {
|
|
|
2591
2591
|
|
|
2592
2592
|
|
|
2593
2593
|
|
|
2594
|
-
|
|
2594
|
+
|
|
2595
|
+
|
|
2595
2596
|
|
|
2596
2597
|
|
|
2597
2598
|
class Meeting {
|
|
@@ -2603,6 +2604,7 @@ class Meeting {
|
|
|
2603
2604
|
|
|
2604
2605
|
|
|
2605
2606
|
|
|
2607
|
+
|
|
2606
2608
|
|
|
2607
2609
|
|
|
2608
2610
|
static parse(plain ) {
|
|
@@ -2614,6 +2616,7 @@ class Meeting {
|
|
|
2614
2616
|
port: plain.port,
|
|
2615
2617
|
uuid: plain.uuid,
|
|
2616
2618
|
number: plain.number,
|
|
2619
|
+
persistent: plain.persistent,
|
|
2617
2620
|
});
|
|
2618
2621
|
}
|
|
2619
2622
|
|
|
@@ -2621,7 +2624,7 @@ class Meeting {
|
|
|
2621
2624
|
return newFrom(meeting, Meeting);
|
|
2622
2625
|
}
|
|
2623
2626
|
|
|
2624
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
2627
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
2625
2628
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2626
2629
|
this.uri = uri;
|
|
2627
2630
|
this.name = name;
|
|
@@ -2629,6 +2632,7 @@ class Meeting {
|
|
|
2629
2632
|
this.port = port;
|
|
2630
2633
|
this.uuid = uuid;
|
|
2631
2634
|
this.number = number;
|
|
2635
|
+
this.persistent = persistent;
|
|
2632
2636
|
|
|
2633
2637
|
// Useful to compare instead of instanceof with minified code
|
|
2634
2638
|
this.type = 'Meeting';
|
|
@@ -3192,7 +3196,7 @@ class Recording {
|
|
|
3192
3196
|
|
|
3193
3197
|
|
|
3194
3198
|
|
|
3195
|
-
static parseMany(recordings
|
|
3199
|
+
static parseMany(recordings = []) {
|
|
3196
3200
|
return recordings.map(item => Recording.parse(item));
|
|
3197
3201
|
}
|
|
3198
3202
|
|
|
@@ -3318,7 +3322,7 @@ class CallLog {
|
|
|
3318
3322
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3319
3323
|
start: moment__default['default'](plain.start).toDate(),
|
|
3320
3324
|
end: plain.end ? moment__default['default'](plain.end).toDate() : null,
|
|
3321
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3325
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3322
3326
|
});
|
|
3323
3327
|
}
|
|
3324
3328
|
|