@twilio/rtc-diagnostics
Version:
Various diagnostics functions to help analyze connections to Twilio
121 lines (108 loc) • 4.37 kB
text/typescript
/**
* The WebRTC API's [RTCIceCandidateStats](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidateStats)
* dictionary which provides information related to an ICE candidate.
* @internalapi
*/
export interface RTCIceCandidateStats {
[key: string]: any;
}
/**
* Represents the WebRTC stats for the ICE candidate pair used to connect to media, if candidates were selected.
* @internalapi
*/
export interface RTCSelectedIceCandidatePairStats {
/**
* An [RTCIceCandidateStats](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidateStats)
* object which provides information related to the selected local ICE candidate.
*/
localCandidate: RTCIceCandidateStats;
/**
* An [RTCIceCandidateStats](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidateStats)
* object which provides information related to the selected remote ICE candidate.
*/
remoteCandidate: RTCIceCandidateStats;
}
/**
* A WebRTC stats report containing relevant information about selected and gathered ICE candidates.
* @internalapi
*/
export interface RTCIceCandidateStatsReport {
/**
* An array of WebRTC stats for the ICE candidates gathered when connecting to media.
*/
iceCandidateStats: RTCIceCandidateStats[];
/**
* A WebRTC stats for the ICE candidate pair used to connect to media, if candidates were selected.
*/
selectedIceCandidatePairStats?: RTCSelectedIceCandidatePairStats;
}
/**
* The RTCStats dictionary is the basic statistics object used by WebRTC's statistics monitoring model,
* providing the properties required of all statistics data objects.
* See [RTCStats](https://developer.mozilla.org/en-US/docs/Web/API/RTCStats)
* @internalapi
*/
export interface RTCStats {
[key: string]: any;
/**
* Uniquely identifies the stats object
*/
id: string;
/**
* Indicates the type of statistics the object contains,
* taken from the enum type [RTCStatsType](https://developer.mozilla.org/en-US/docs/Web/API/RTCStatsType).
*/
type: string;
}
/**
* @internalapi
* Generate a WebRTC stats report containing relevant information about ICE candidates for
* the given [PeerConnection](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection)
* @param peerConnection
*/
export async function getRTCIceCandidateStatsReport(peerConnection: RTCPeerConnection): Promise<RTCIceCandidateStatsReport> {
const report = await peerConnection.getStats() as Map<string, RTCStats>;
const statsArrays = Array.from(report.values()).reduce((result, stat) => {
switch (stat.type) {
case 'candidate-pair':
result.candidatePairs.push(stat);
break;
case 'local-candidate':
result.localCandidates.push(stat);
break;
case 'remote-candidate':
result.remoteCandidates.push(stat);
break;
case 'transport':
// This transport is the one being used if selectedCandidatePairId is populated
if (stat.selectedCandidatePairId) {
result.transport = stat;
}
break;
}
return result;
}, { candidatePairs: [], localCandidates: [], remoteCandidates: [] } as Record<string, RTCStats[] | RTCStats>);
const candidatePairs = statsArrays.candidatePairs as RTCStats[];
const localCandidates = statsArrays.localCandidates as RTCStats[];
const remoteCandidates = statsArrays.remoteCandidates as RTCStats[];
const transport = statsArrays.transport as RTCStats;
// This is a report containing information about the selected candidates, such as IDs
// This is coming from WebRTC stats directly and doesn't contain the actual ICE Candidates info
const selectedCandidatePairReport = candidatePairs.find(pair =>
// Firefox
pair.selected ||
// Spec-compliant way
(transport && pair.id === transport.selectedCandidatePairId),
);
let selectedIceCandidatePairStats;
if (selectedCandidatePairReport) {
selectedIceCandidatePairStats = {
localCandidate: localCandidates.find(candidate => candidate.id === selectedCandidatePairReport.localCandidateId),
remoteCandidate: remoteCandidates.find(candidate => candidate.id === selectedCandidatePairReport.remoteCandidateId),
};
}
return {
iceCandidateStats: [...localCandidates, ...remoteCandidates],
selectedIceCandidatePairStats,
} as RTCIceCandidateStatsReport;
}