diff --git a/openvidu-browser/src/OpenVidu/Stream.ts b/openvidu-browser/src/OpenVidu/Stream.ts index 89f8732d..35e02898 100644 --- a/openvidu-browser/src/OpenVidu/Stream.ts +++ b/openvidu-browser/src/OpenVidu/Stream.ts @@ -747,6 +747,17 @@ export class Stream extends EventDispatcher { return (!this.inboundStreamOpts && !!this.outboundStreamOpts); } + /** + * @hidden + */ + getSelectedIceCandidate(): Promise { + return new Promise((resolve, reject) => { + this.webRtcStats.getSelectedIceCandidateInfo() + .then(report => resolve(report)) + .catch(error => reject(error)); + }); + } + /** * @hidden */ diff --git a/openvidu-browser/src/OpenViduInternal/WebRtcStats/WebRtcStats.ts b/openvidu-browser/src/OpenViduInternal/WebRtcStats/WebRtcStats.ts index cd8f0b27..478718ba 100644 --- a/openvidu-browser/src/OpenViduInternal/WebRtcStats/WebRtcStats.ts +++ b/openvidu-browser/src/OpenViduInternal/WebRtcStats/WebRtcStats.ts @@ -85,6 +85,69 @@ export class WebRtcStats { } } + // Used in test-app + public getSelectedIceCandidateInfo(): Promise { + return new Promise((resolve, reject) => { + this.getStats().then( + (stats) => { + if (platform.isChromeBrowser() || platform.isChromeMobileBrowser() || platform.isOperaBrowser() || platform.isOperaMobileBrowser()) { + let localCandidateId, remoteCandidateId, googCandidatePair; + const localCandidates = {}; + const remoteCandidates = {}; + for (const key in stats) { + const stat = stats[key]; + if (stat.type === 'localcandidate') { + localCandidates[stat.id] = stat; + } else if (stat.type === 'remotecandidate') { + remoteCandidates[stat.id] = stat; + } else if (stat.type === 'googCandidatePair' && (stat.googActiveConnection === 'true')) { + googCandidatePair = stat; + localCandidateId = stat.localCandidateId; + remoteCandidateId = stat.remoteCandidateId; + } + } + let finalLocalCandidate = localCandidates[localCandidateId]; + if (!!finalLocalCandidate) { + const candList = this.stream.getLocalIceCandidateList(); + const cand = candList.filter((c: RTCIceCandidate) => { + return (!!c.candidate && + c.candidate.indexOf(finalLocalCandidate.ipAddress) >= 0 && + c.candidate.indexOf(finalLocalCandidate.portNumber) >= 0 && + c.candidate.indexOf(finalLocalCandidate.priority) >= 0); + }); + finalLocalCandidate.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find local candidate in list of sent ICE candidates'; + } else { + finalLocalCandidate = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used'; + } + + let finalRemoteCandidate = remoteCandidates[remoteCandidateId]; + if (!!finalRemoteCandidate) { + const candList = this.stream.getRemoteIceCandidateList(); + const cand = candList.filter((c: RTCIceCandidate) => { + return (!!c.candidate && + c.candidate.indexOf(finalRemoteCandidate.ipAddress) >= 0 && + c.candidate.indexOf(finalRemoteCandidate.portNumber) >= 0 && + c.candidate.indexOf(finalRemoteCandidate.priority) >= 0); + }); + finalRemoteCandidate.raw = !!cand[0] ? cand[0].candidate : 'ERROR: Cannot find remote candidate in list of received ICE candidates'; + } else { + finalRemoteCandidate = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used'; + } + + resolve({ + googCandidatePair, + localCandidate: finalLocalCandidate, + remoteCandidate: finalRemoteCandidate + }); + } else { + reject('Selected ICE candidate info only available for Chrome'); + } + }).catch((error) => { + reject(error); + }); + }); + } + public stopWebRtcStats() { if (this.webRtcStatsEnabled) { clearInterval(this.webRtcStatsIntervalId);