react-jssip-kit 0.7.8 → 0.7.9
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/index.cjs +234 -161
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +234 -161
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -57,6 +57,11 @@ type SipConfiguration = Omit<UAConfiguration, "password" | "uri"> & {
|
|
|
57
57
|
* Maximum allowed concurrent sessions. Additional sessions are rejected.
|
|
58
58
|
*/
|
|
59
59
|
maxSessionCount?: number;
|
|
60
|
+
/**
|
|
61
|
+
* Delay before calling event.ready() on ICE candidates (ms).
|
|
62
|
+
* When set, ICE gathering can be short-circuited for slow connections.
|
|
63
|
+
*/
|
|
64
|
+
iceCandidateReadyDelayMs?: number;
|
|
60
65
|
};
|
|
61
66
|
|
|
62
67
|
type StartOpts = {
|
|
@@ -178,6 +183,7 @@ declare class SipClient extends EventTargetEmitter<JsSIPEventMap> {
|
|
|
178
183
|
private readonly errorHandler;
|
|
179
184
|
private debugPattern?;
|
|
180
185
|
private maxSessionCount;
|
|
186
|
+
private iceCandidateReadyDelayMs?;
|
|
181
187
|
private sessionManager;
|
|
182
188
|
private lifecycle;
|
|
183
189
|
private micRecovery;
|
package/dist/index.d.ts
CHANGED
|
@@ -57,6 +57,11 @@ type SipConfiguration = Omit<UAConfiguration, "password" | "uri"> & {
|
|
|
57
57
|
* Maximum allowed concurrent sessions. Additional sessions are rejected.
|
|
58
58
|
*/
|
|
59
59
|
maxSessionCount?: number;
|
|
60
|
+
/**
|
|
61
|
+
* Delay before calling event.ready() on ICE candidates (ms).
|
|
62
|
+
* When set, ICE gathering can be short-circuited for slow connections.
|
|
63
|
+
*/
|
|
64
|
+
iceCandidateReadyDelayMs?: number;
|
|
60
65
|
};
|
|
61
66
|
|
|
62
67
|
type StartOpts = {
|
|
@@ -178,6 +183,7 @@ declare class SipClient extends EventTargetEmitter<JsSIPEventMap> {
|
|
|
178
183
|
private readonly errorHandler;
|
|
179
184
|
private debugPattern?;
|
|
180
185
|
private maxSessionCount;
|
|
186
|
+
private iceCandidateReadyDelayMs?;
|
|
181
187
|
private sessionManager;
|
|
182
188
|
private lifecycle;
|
|
183
189
|
private micRecovery;
|
package/dist/index.js
CHANGED
|
@@ -468,6 +468,175 @@ function removeSessionState(state, sessionId) {
|
|
|
468
468
|
});
|
|
469
469
|
}
|
|
470
470
|
|
|
471
|
+
// src/jssip-lib/sip/debugLogging.ts
|
|
472
|
+
var describePc = (pc) => ({
|
|
473
|
+
connectionState: pc?.connectionState,
|
|
474
|
+
signalingState: pc?.signalingState,
|
|
475
|
+
iceConnectionState: pc?.iceConnectionState
|
|
476
|
+
});
|
|
477
|
+
var SipDebugLogger = class {
|
|
478
|
+
constructor() {
|
|
479
|
+
this.enabled = false;
|
|
480
|
+
this.statsStops = /* @__PURE__ */ new Map();
|
|
481
|
+
}
|
|
482
|
+
setEnabled(enabled) {
|
|
483
|
+
this.enabled = enabled;
|
|
484
|
+
if (!enabled) {
|
|
485
|
+
this.statsStops.forEach((stop) => stop());
|
|
486
|
+
this.statsStops.clear();
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
isEnabled() {
|
|
490
|
+
return this.enabled;
|
|
491
|
+
}
|
|
492
|
+
logLocalAudioError(sessionId, message, pc, extra) {
|
|
493
|
+
if (!this.enabled)
|
|
494
|
+
return;
|
|
495
|
+
console.error(message, {
|
|
496
|
+
sessionId,
|
|
497
|
+
pc: describePc(pc),
|
|
498
|
+
...extra
|
|
499
|
+
});
|
|
500
|
+
void this.logOutboundStats(sessionId, pc, message);
|
|
501
|
+
}
|
|
502
|
+
logRemoteAudioError(sessionId, message, pc, extra) {
|
|
503
|
+
if (!this.enabled)
|
|
504
|
+
return;
|
|
505
|
+
console.error(message, {
|
|
506
|
+
sessionId,
|
|
507
|
+
pc: describePc(pc),
|
|
508
|
+
...extra
|
|
509
|
+
});
|
|
510
|
+
void this.logInboundStats(sessionId, pc, message);
|
|
511
|
+
}
|
|
512
|
+
logMicRecoveryDrop(payload) {
|
|
513
|
+
if (!this.enabled)
|
|
514
|
+
return;
|
|
515
|
+
console.error("[sip] microphone dropped", payload);
|
|
516
|
+
}
|
|
517
|
+
logIceReady(sessionId, payload) {
|
|
518
|
+
if (!this.enabled)
|
|
519
|
+
return;
|
|
520
|
+
console.info("[sip] ice ready", { sessionId, ...payload });
|
|
521
|
+
}
|
|
522
|
+
logIceReadyConfig(sessionId, delayMs) {
|
|
523
|
+
if (!this.enabled)
|
|
524
|
+
return;
|
|
525
|
+
console.info("[sip] ice ready config", { sessionId, delayMs });
|
|
526
|
+
}
|
|
527
|
+
startCallStatsLogging(sessionId, session) {
|
|
528
|
+
if (!this.enabled || this.statsStops.has(sessionId))
|
|
529
|
+
return;
|
|
530
|
+
let pc = session?.connection ?? null;
|
|
531
|
+
const onPeer = (data) => {
|
|
532
|
+
pc = data.peerconnection;
|
|
533
|
+
};
|
|
534
|
+
session.on?.("peerconnection", onPeer);
|
|
535
|
+
const intervalMs = 3e3;
|
|
536
|
+
const logStats = async () => {
|
|
537
|
+
if (!this.enabled || !pc?.getStats)
|
|
538
|
+
return;
|
|
539
|
+
try {
|
|
540
|
+
const report = await pc.getStats();
|
|
541
|
+
const { outboundAudio, inboundAudio } = collectAudioStats(report);
|
|
542
|
+
console.info("[sip] call stats", {
|
|
543
|
+
sessionId,
|
|
544
|
+
pc: describePc(pc),
|
|
545
|
+
outboundAudio,
|
|
546
|
+
inboundAudio
|
|
547
|
+
});
|
|
548
|
+
} catch (err) {
|
|
549
|
+
console.error("[sip] call stats failed", { sessionId, error: err });
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
const timer = setInterval(() => {
|
|
553
|
+
void logStats();
|
|
554
|
+
}, intervalMs);
|
|
555
|
+
void logStats();
|
|
556
|
+
const stop = () => {
|
|
557
|
+
clearInterval(timer);
|
|
558
|
+
session.off?.("peerconnection", onPeer);
|
|
559
|
+
this.statsStops.delete(sessionId);
|
|
560
|
+
};
|
|
561
|
+
this.statsStops.set(sessionId, stop);
|
|
562
|
+
}
|
|
563
|
+
stopCallStatsLogging(sessionId) {
|
|
564
|
+
const stop = this.statsStops.get(sessionId);
|
|
565
|
+
if (stop)
|
|
566
|
+
stop();
|
|
567
|
+
}
|
|
568
|
+
async logOutboundStats(sessionId, pc, context) {
|
|
569
|
+
if (!pc?.getStats)
|
|
570
|
+
return;
|
|
571
|
+
try {
|
|
572
|
+
const report = await pc.getStats();
|
|
573
|
+
const { outboundAudio } = collectAudioStats(report);
|
|
574
|
+
if (outboundAudio.length) {
|
|
575
|
+
console.info("[sip] outgoing audio stats", {
|
|
576
|
+
sessionId,
|
|
577
|
+
context,
|
|
578
|
+
outboundAudio
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
} catch (err) {
|
|
582
|
+
console.error("[sip] outgoing audio stats failed", {
|
|
583
|
+
sessionId,
|
|
584
|
+
context,
|
|
585
|
+
error: err
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
async logInboundStats(sessionId, pc, context) {
|
|
590
|
+
if (!pc?.getStats)
|
|
591
|
+
return;
|
|
592
|
+
try {
|
|
593
|
+
const report = await pc.getStats();
|
|
594
|
+
const { inboundAudio } = collectAudioStats(report);
|
|
595
|
+
if (inboundAudio.length) {
|
|
596
|
+
console.error("[sip] incoming audio stats", {
|
|
597
|
+
sessionId,
|
|
598
|
+
context,
|
|
599
|
+
inboundAudio
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
} catch (err) {
|
|
603
|
+
console.error("[sip] incoming audio stats failed", {
|
|
604
|
+
sessionId,
|
|
605
|
+
context,
|
|
606
|
+
error: err
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
var sipDebugLogger = new SipDebugLogger();
|
|
612
|
+
function collectAudioStats(report) {
|
|
613
|
+
const outboundAudio = [];
|
|
614
|
+
const inboundAudio = [];
|
|
615
|
+
report.forEach((stat) => {
|
|
616
|
+
const kind = stat.kind ?? stat.mediaType;
|
|
617
|
+
if (stat.type === "outbound-rtp" && kind === "audio") {
|
|
618
|
+
outboundAudio.push({
|
|
619
|
+
id: stat.id,
|
|
620
|
+
packetsSent: stat.packetsSent,
|
|
621
|
+
bytesSent: stat.bytesSent,
|
|
622
|
+
jitter: stat.jitter,
|
|
623
|
+
roundTripTime: stat.roundTripTime
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
if (stat.type === "inbound-rtp" && kind === "audio") {
|
|
627
|
+
inboundAudio.push({
|
|
628
|
+
id: stat.id,
|
|
629
|
+
packetsReceived: stat.packetsReceived,
|
|
630
|
+
packetsLost: stat.packetsLost,
|
|
631
|
+
bytesReceived: stat.bytesReceived,
|
|
632
|
+
jitter: stat.jitter,
|
|
633
|
+
roundTripTime: stat.roundTripTime
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
return { outboundAudio, inboundAudio };
|
|
638
|
+
}
|
|
639
|
+
|
|
471
640
|
// src/jssip-lib/sip/handlers/sessionHandlers.ts
|
|
472
641
|
function createSessionHandlers(deps) {
|
|
473
642
|
const {
|
|
@@ -476,8 +645,20 @@ function createSessionHandlers(deps) {
|
|
|
476
645
|
rtc,
|
|
477
646
|
detachSessionHandlers,
|
|
478
647
|
onSessionFailed,
|
|
479
|
-
sessionId
|
|
648
|
+
sessionId,
|
|
649
|
+
iceCandidateReadyDelayMs
|
|
480
650
|
} = deps;
|
|
651
|
+
let iceReadyCalled = false;
|
|
652
|
+
let iceReadyTimer = null;
|
|
653
|
+
const clearIceReadyTimer = () => {
|
|
654
|
+
if (!iceReadyTimer)
|
|
655
|
+
return;
|
|
656
|
+
clearTimeout(iceReadyTimer);
|
|
657
|
+
iceReadyTimer = null;
|
|
658
|
+
};
|
|
659
|
+
if (typeof iceCandidateReadyDelayMs === "number") {
|
|
660
|
+
sipDebugLogger.logIceReadyConfig(sessionId, iceCandidateReadyDelayMs);
|
|
661
|
+
}
|
|
481
662
|
return {
|
|
482
663
|
progress: (e) => {
|
|
483
664
|
emitter.emit("progress", e);
|
|
@@ -500,6 +681,7 @@ function createSessionHandlers(deps) {
|
|
|
500
681
|
},
|
|
501
682
|
ended: (e) => {
|
|
502
683
|
emitter.emit("ended", e);
|
|
684
|
+
clearIceReadyTimer();
|
|
503
685
|
detachSessionHandlers();
|
|
504
686
|
rtc.cleanup();
|
|
505
687
|
const nextSessions = state.getState().sessions.filter((s) => s.id !== sessionId);
|
|
@@ -509,6 +691,7 @@ function createSessionHandlers(deps) {
|
|
|
509
691
|
},
|
|
510
692
|
failed: (e) => {
|
|
511
693
|
emitter.emit("failed", e);
|
|
694
|
+
clearIceReadyTimer();
|
|
512
695
|
detachSessionHandlers();
|
|
513
696
|
rtc.cleanup();
|
|
514
697
|
const cause = e?.cause || "call failed";
|
|
@@ -537,13 +720,55 @@ function createSessionHandlers(deps) {
|
|
|
537
720
|
reinvite: (e) => emitter.emit("reinvite", e),
|
|
538
721
|
update: (e) => emitter.emit("update", e),
|
|
539
722
|
sdp: (e) => emitter.emit("sdp", e),
|
|
540
|
-
icecandidate: (e) =>
|
|
723
|
+
icecandidate: (e) => {
|
|
724
|
+
const candidate = e?.candidate;
|
|
725
|
+
const ready = typeof e?.ready === "function" ? e.ready : null;
|
|
726
|
+
const delayMs = typeof iceCandidateReadyDelayMs === "number" ? iceCandidateReadyDelayMs : null;
|
|
727
|
+
if (!iceReadyCalled && ready && delayMs != null) {
|
|
728
|
+
if (candidate?.type === "srflx" && candidate?.relatedAddress != null && candidate?.relatedPort != null) {
|
|
729
|
+
iceReadyCalled = true;
|
|
730
|
+
if (iceReadyTimer) {
|
|
731
|
+
clearTimeout(iceReadyTimer);
|
|
732
|
+
iceReadyTimer = null;
|
|
733
|
+
}
|
|
734
|
+
sipDebugLogger.logIceReady(sessionId, {
|
|
735
|
+
source: "srflx",
|
|
736
|
+
delayMs,
|
|
737
|
+
candidateType: candidate?.type
|
|
738
|
+
});
|
|
739
|
+
ready();
|
|
740
|
+
} else if (!iceReadyTimer && delayMs > 0) {
|
|
741
|
+
iceReadyTimer = setTimeout(() => {
|
|
742
|
+
iceReadyTimer = null;
|
|
743
|
+
if (iceReadyCalled)
|
|
744
|
+
return;
|
|
745
|
+
iceReadyCalled = true;
|
|
746
|
+
sipDebugLogger.logIceReady(sessionId, {
|
|
747
|
+
source: "timer",
|
|
748
|
+
delayMs,
|
|
749
|
+
candidateType: candidate?.type
|
|
750
|
+
});
|
|
751
|
+
ready();
|
|
752
|
+
}, delayMs);
|
|
753
|
+
} else if (delayMs === 0) {
|
|
754
|
+
iceReadyCalled = true;
|
|
755
|
+
sipDebugLogger.logIceReady(sessionId, {
|
|
756
|
+
source: "immediate",
|
|
757
|
+
delayMs,
|
|
758
|
+
candidateType: candidate?.type
|
|
759
|
+
});
|
|
760
|
+
ready();
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
emitter.emit("icecandidate", e);
|
|
764
|
+
},
|
|
541
765
|
refer: (e) => emitter.emit("refer", e),
|
|
542
766
|
replaces: (e) => emitter.emit("replaces", e),
|
|
543
767
|
newDTMF: (e) => emitter.emit("newDTMF", e),
|
|
544
768
|
newInfo: (e) => emitter.emit("newInfo", e),
|
|
545
769
|
getusermediafailed: (e) => {
|
|
546
770
|
emitter.emit("getusermediafailed", e);
|
|
771
|
+
clearIceReadyTimer();
|
|
547
772
|
detachSessionHandlers();
|
|
548
773
|
rtc.cleanup();
|
|
549
774
|
onSessionFailed("getUserMedia failed", e);
|
|
@@ -553,6 +778,7 @@ function createSessionHandlers(deps) {
|
|
|
553
778
|
},
|
|
554
779
|
"peerconnection:createofferfailed": (e) => {
|
|
555
780
|
emitter.emit("peerconnection:createofferfailed", e);
|
|
781
|
+
clearIceReadyTimer();
|
|
556
782
|
detachSessionHandlers();
|
|
557
783
|
rtc.cleanup();
|
|
558
784
|
onSessionFailed("peer connection createOffer failed", e);
|
|
@@ -562,6 +788,7 @@ function createSessionHandlers(deps) {
|
|
|
562
788
|
},
|
|
563
789
|
"peerconnection:createanswerfailed": (e) => {
|
|
564
790
|
emitter.emit("peerconnection:createanswerfailed", e);
|
|
791
|
+
clearIceReadyTimer();
|
|
565
792
|
detachSessionHandlers();
|
|
566
793
|
rtc.cleanup();
|
|
567
794
|
onSessionFailed("peer connection createAnswer failed", e);
|
|
@@ -571,6 +798,7 @@ function createSessionHandlers(deps) {
|
|
|
571
798
|
},
|
|
572
799
|
"peerconnection:setlocaldescriptionfailed": (e) => {
|
|
573
800
|
emitter.emit("peerconnection:setlocaldescriptionfailed", e);
|
|
801
|
+
clearIceReadyTimer();
|
|
574
802
|
detachSessionHandlers();
|
|
575
803
|
rtc.cleanup();
|
|
576
804
|
onSessionFailed("peer connection setLocalDescription failed", e);
|
|
@@ -580,6 +808,7 @@ function createSessionHandlers(deps) {
|
|
|
580
808
|
},
|
|
581
809
|
"peerconnection:setremotedescriptionfailed": (e) => {
|
|
582
810
|
emitter.emit("peerconnection:setremotedescriptionfailed", e);
|
|
811
|
+
clearIceReadyTimer();
|
|
583
812
|
detachSessionHandlers();
|
|
584
813
|
rtc.cleanup();
|
|
585
814
|
onSessionFailed("peer connection setRemoteDescription failed", e);
|
|
@@ -832,165 +1061,6 @@ var SessionManager = class {
|
|
|
832
1061
|
}
|
|
833
1062
|
};
|
|
834
1063
|
|
|
835
|
-
// src/jssip-lib/sip/debugLogging.ts
|
|
836
|
-
var describePc = (pc) => ({
|
|
837
|
-
connectionState: pc?.connectionState,
|
|
838
|
-
signalingState: pc?.signalingState,
|
|
839
|
-
iceConnectionState: pc?.iceConnectionState
|
|
840
|
-
});
|
|
841
|
-
var SipDebugLogger = class {
|
|
842
|
-
constructor() {
|
|
843
|
-
this.enabled = false;
|
|
844
|
-
this.statsStops = /* @__PURE__ */ new Map();
|
|
845
|
-
}
|
|
846
|
-
setEnabled(enabled) {
|
|
847
|
-
this.enabled = enabled;
|
|
848
|
-
if (!enabled) {
|
|
849
|
-
this.statsStops.forEach((stop) => stop());
|
|
850
|
-
this.statsStops.clear();
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
isEnabled() {
|
|
854
|
-
return this.enabled;
|
|
855
|
-
}
|
|
856
|
-
logLocalAudioError(sessionId, message, pc, extra) {
|
|
857
|
-
if (!this.enabled)
|
|
858
|
-
return;
|
|
859
|
-
console.error(message, {
|
|
860
|
-
sessionId,
|
|
861
|
-
pc: describePc(pc),
|
|
862
|
-
...extra
|
|
863
|
-
});
|
|
864
|
-
void this.logOutboundStats(sessionId, pc, message);
|
|
865
|
-
}
|
|
866
|
-
logRemoteAudioError(sessionId, message, pc, extra) {
|
|
867
|
-
if (!this.enabled)
|
|
868
|
-
return;
|
|
869
|
-
console.error(message, {
|
|
870
|
-
sessionId,
|
|
871
|
-
pc: describePc(pc),
|
|
872
|
-
...extra
|
|
873
|
-
});
|
|
874
|
-
void this.logInboundStats(sessionId, pc, message);
|
|
875
|
-
}
|
|
876
|
-
logMicRecoveryDrop(payload) {
|
|
877
|
-
if (!this.enabled)
|
|
878
|
-
return;
|
|
879
|
-
console.error("[sip] microphone dropped", payload);
|
|
880
|
-
}
|
|
881
|
-
startCallStatsLogging(sessionId, session) {
|
|
882
|
-
if (!this.enabled || this.statsStops.has(sessionId))
|
|
883
|
-
return;
|
|
884
|
-
let pc = session?.connection ?? null;
|
|
885
|
-
const onPeer = (data) => {
|
|
886
|
-
pc = data.peerconnection;
|
|
887
|
-
};
|
|
888
|
-
session.on?.("peerconnection", onPeer);
|
|
889
|
-
const intervalMs = 3e3;
|
|
890
|
-
const logStats = async () => {
|
|
891
|
-
if (!this.enabled || !pc?.getStats)
|
|
892
|
-
return;
|
|
893
|
-
try {
|
|
894
|
-
const report = await pc.getStats();
|
|
895
|
-
const { outboundAudio, inboundAudio } = collectAudioStats(report);
|
|
896
|
-
console.info("[sip] call stats", {
|
|
897
|
-
sessionId,
|
|
898
|
-
pc: describePc(pc),
|
|
899
|
-
outboundAudio,
|
|
900
|
-
inboundAudio
|
|
901
|
-
});
|
|
902
|
-
} catch (err) {
|
|
903
|
-
console.error("[sip] call stats failed", { sessionId, error: err });
|
|
904
|
-
}
|
|
905
|
-
};
|
|
906
|
-
const timer = setInterval(() => {
|
|
907
|
-
void logStats();
|
|
908
|
-
}, intervalMs);
|
|
909
|
-
void logStats();
|
|
910
|
-
const stop = () => {
|
|
911
|
-
clearInterval(timer);
|
|
912
|
-
session.off?.("peerconnection", onPeer);
|
|
913
|
-
this.statsStops.delete(sessionId);
|
|
914
|
-
};
|
|
915
|
-
this.statsStops.set(sessionId, stop);
|
|
916
|
-
}
|
|
917
|
-
stopCallStatsLogging(sessionId) {
|
|
918
|
-
const stop = this.statsStops.get(sessionId);
|
|
919
|
-
if (stop)
|
|
920
|
-
stop();
|
|
921
|
-
}
|
|
922
|
-
async logOutboundStats(sessionId, pc, context) {
|
|
923
|
-
if (!pc?.getStats)
|
|
924
|
-
return;
|
|
925
|
-
try {
|
|
926
|
-
const report = await pc.getStats();
|
|
927
|
-
const { outboundAudio } = collectAudioStats(report);
|
|
928
|
-
if (outboundAudio.length) {
|
|
929
|
-
console.info("[sip] outgoing audio stats", {
|
|
930
|
-
sessionId,
|
|
931
|
-
context,
|
|
932
|
-
outboundAudio
|
|
933
|
-
});
|
|
934
|
-
}
|
|
935
|
-
} catch (err) {
|
|
936
|
-
console.error("[sip] outgoing audio stats failed", {
|
|
937
|
-
sessionId,
|
|
938
|
-
context,
|
|
939
|
-
error: err
|
|
940
|
-
});
|
|
941
|
-
}
|
|
942
|
-
}
|
|
943
|
-
async logInboundStats(sessionId, pc, context) {
|
|
944
|
-
if (!pc?.getStats)
|
|
945
|
-
return;
|
|
946
|
-
try {
|
|
947
|
-
const report = await pc.getStats();
|
|
948
|
-
const { inboundAudio } = collectAudioStats(report);
|
|
949
|
-
if (inboundAudio.length) {
|
|
950
|
-
console.error("[sip] incoming audio stats", {
|
|
951
|
-
sessionId,
|
|
952
|
-
context,
|
|
953
|
-
inboundAudio
|
|
954
|
-
});
|
|
955
|
-
}
|
|
956
|
-
} catch (err) {
|
|
957
|
-
console.error("[sip] incoming audio stats failed", {
|
|
958
|
-
sessionId,
|
|
959
|
-
context,
|
|
960
|
-
error: err
|
|
961
|
-
});
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
};
|
|
965
|
-
var sipDebugLogger = new SipDebugLogger();
|
|
966
|
-
function collectAudioStats(report) {
|
|
967
|
-
const outboundAudio = [];
|
|
968
|
-
const inboundAudio = [];
|
|
969
|
-
report.forEach((stat) => {
|
|
970
|
-
const kind = stat.kind ?? stat.mediaType;
|
|
971
|
-
if (stat.type === "outbound-rtp" && kind === "audio") {
|
|
972
|
-
outboundAudio.push({
|
|
973
|
-
id: stat.id,
|
|
974
|
-
packetsSent: stat.packetsSent,
|
|
975
|
-
bytesSent: stat.bytesSent,
|
|
976
|
-
jitter: stat.jitter,
|
|
977
|
-
roundTripTime: stat.roundTripTime
|
|
978
|
-
});
|
|
979
|
-
}
|
|
980
|
-
if (stat.type === "inbound-rtp" && kind === "audio") {
|
|
981
|
-
inboundAudio.push({
|
|
982
|
-
id: stat.id,
|
|
983
|
-
packetsReceived: stat.packetsReceived,
|
|
984
|
-
packetsLost: stat.packetsLost,
|
|
985
|
-
bytesReceived: stat.bytesReceived,
|
|
986
|
-
jitter: stat.jitter,
|
|
987
|
-
roundTripTime: stat.roundTripTime
|
|
988
|
-
});
|
|
989
|
-
}
|
|
990
|
-
});
|
|
991
|
-
return { outboundAudio, inboundAudio };
|
|
992
|
-
}
|
|
993
|
-
|
|
994
1064
|
// src/jssip-lib/sip/sessionLifecycle.ts
|
|
995
1065
|
var SessionLifecycle = class {
|
|
996
1066
|
constructor(deps) {
|
|
@@ -1635,9 +1705,11 @@ var SipClient = class extends EventTargetEmitter {
|
|
|
1635
1705
|
micRecoveryIntervalMs,
|
|
1636
1706
|
micRecoveryMaxRetries,
|
|
1637
1707
|
maxSessionCount,
|
|
1708
|
+
iceCandidateReadyDelayMs,
|
|
1638
1709
|
...uaCfg
|
|
1639
1710
|
} = config;
|
|
1640
1711
|
this.maxSessionCount = typeof maxSessionCount === "number" ? maxSessionCount : Infinity;
|
|
1712
|
+
this.iceCandidateReadyDelayMs = typeof iceCandidateReadyDelayMs === "number" ? iceCandidateReadyDelayMs : void 0;
|
|
1641
1713
|
this.micRecovery.configure({
|
|
1642
1714
|
enabled: Boolean(enableMicRecovery),
|
|
1643
1715
|
intervalMs: micRecoveryIntervalMs,
|
|
@@ -1785,6 +1857,7 @@ var SipClient = class extends EventTargetEmitter {
|
|
|
1785
1857
|
emitError: (raw, code, fallback) => this.emitError(raw, code, fallback),
|
|
1786
1858
|
onSessionFailed: (err, event) => this.onSessionFailed(err, event),
|
|
1787
1859
|
enableMicrophoneRecovery: (confirmedSessionId) => this.micRecovery.enable(confirmedSessionId),
|
|
1860
|
+
iceCandidateReadyDelayMs: this.iceCandidateReadyDelayMs,
|
|
1788
1861
|
sessionId
|
|
1789
1862
|
});
|
|
1790
1863
|
}
|