diff --git a/src/modules/stream/stream-badges.ts b/src/modules/stream/stream-badges.ts index dfbf2a1..b4f6b7a 100755 --- a/src/modules/stream/stream-badges.ts +++ b/src/modules/stream/stream-badges.ts @@ -253,8 +253,9 @@ export class StreamBadges { const allAudioCodecs: Record = {}; let audioCodecId; - const allCandidates: Record = {}; - let candidateId; + const allCandidatePairs: Record = {}; + const allRemoteCandidates: Record = {}; + let candidatePairId; stats.forEach((stat: RTCBasicStat) => { if (stat.type === 'codec') { @@ -275,10 +276,12 @@ export class StreamBadges { } else if (stat.kind === 'audio') { audioCodecId = stat.codecId; } - } else if (stat.type === 'candidate-pair' && stat.packetsReceived > 0 && stat.state === 'succeeded') { - candidateId = stat.remoteCandidateId; + } else if (stat.type === 'transport' && (stat as unknown as RTCTransportStats).selectedCandidatePairId) { + candidatePairId = (stat as unknown as RTCTransportStats).selectedCandidatePairId; + } else if (stat.type === 'candidate-pair') { + allCandidatePairs[stat.id] = (stat as unknown as RTCIceCandidatePairStats).remoteCandidateId; } else if (stat.type === 'remote-candidate') { - allCandidates[stat.id] = stat.address; + allRemoteCandidates[stat.id] = stat.address; } }); @@ -336,12 +339,12 @@ export class StreamBadges { } // Get server type - if (candidateId) { - BxLogger.info('candidate', candidateId, allCandidates); + if (candidatePairId) { + BxLogger.info('candidate', candidatePairId, allCandidatePairs); // Server + Region let text = ''; - const isIpv6 = allCandidates[candidateId].includes(':'); + const isIpv6 = allRemoteCandidates[allCandidatePairs[candidatePairId]].includes(':'); const server = this.serverInfo.server; if (server && server.region) { diff --git a/src/utils/stream-stats-collector.ts b/src/utils/stream-stats-collector.ts index 8bfefc7..9fcda0a 100755 --- a/src/utils/stream-stats-collector.ts +++ b/src/utils/stream-stats-collector.ts @@ -201,6 +201,7 @@ export class StreamStatsCollector { }; private lastVideoStat?: RTCInboundRtpStreamStats | null; + private selectedCandidatePairId: string | null | undefined = null; private constructor() { BxLogger.info(this.LOG_TAG, 'constructor()'); @@ -212,6 +213,22 @@ export class StreamStatsCollector { return; } + // Find selected candidate + if (!this.selectedCandidatePairId) { + let found = false; + stats.forEach(stat => { + if (found || stat.type !== 'transport') { + return; + } + + stat = (stat as unknown as RTCTransportStats); + if (stat.iceState === 'connected' && stat.selectedCandidatePairId) { + this.selectedCandidatePairId = (stat as unknown as RTCTransportStats).selectedCandidatePairId; + found = true; + } + }); + } + stats.forEach(stat => { if (stat.type === 'inbound-rtp' && stat.kind === 'video') { // FPS @@ -256,7 +273,7 @@ export class StreamStatsCollector { dt.current = dt.total / framesDecodedDiff * 1000; this.lastVideoStat = stat; - } else if (stat.type === 'candidate-pair' && stat.packetsReceived > 0 && stat.state === 'succeeded') { + } else if (this.selectedCandidatePairId && stat.type === 'candidate-pair' && stat.id === this.selectedCandidatePairId) { // Round Trip Time const ping = this.currentStats[StreamStat.PING]; ping.current = stat.currentRoundTripTime ? stat.currentRoundTripTime * 1000 : -1;