async getStats()

in src/js/rtc_session.js [905:992]


    async getStats() {
        var timestamp = new Date();

        var impl = async (stream, streamType) => {
            var tracks = [];

            if (!stream) {
                return [];
            }

            switch (streamType) {
                case 'audio_input':
                case 'audio_output':
                    tracks = stream.getAudioTracks();
                    break;
                case 'video_input':
                case 'video_output':
                    tracks = stream.getVideoTracks();
                    break;
                default:
                    throw new Error('Unsupported stream type while trying to get stats: ' + streamType);
            }

            return await Promise.all(tracks.map(async(track) => {
                // get legacy stats report as a promise
                if (this._legacyStatsReportSupport) {
                    var self = this;
                    return new Promise(function(resolve) {
                        self._pc.getStats(function(rawStats) {
                            var digestedStats = extractMediaStatsFromStats(timestamp, rawStats.result(), streamType);
                            if (!digestedStats) {
                                throw new Error('Failed to extract MediaRtpStats from RTCStatsReport for stream type ' + streamType);
                            }
                            resolve(digestedStats);
                        }, track);
                    });
                } else { // get standardized report
                    return this._pc.getStats().then(function(rawStats) {
                        var digestedStats = extractMediaStatsFromStats(timestamp, rawStats, streamType);
                        if (!digestedStats) {
                            throw new Error('Failed to extract MediaRtpStats from RTCStatsReport for stream type ' + streamType);
                        }
                        return digestedStats;
                    });
                }
            }));
        };

        if (this._pc && this._pc.signalingState === 'stable') {
            var statsResult = {
                audio: {
                    input: await impl(this._remoteAudioStream, 'audio_input'),
                    output: await impl(this._localStream, 'audio_output')
                },

                video: {
                    input: await impl(this._remoteVideoStream, 'video_input'),
                    output: await impl(this._localStream, 'video_output')
                }
            };

            // For consistency's sake, coalesce rttMilliseconds into the output for audio and video.
            var rttReducer = (acc, stats) => {
                if (stats.rttMilliseconds !== null && (acc === null || stats.rttMilliseconds > acc)) {
                    acc = stats.rttMilliseconds;
                }
                stats._rttMilliseconds = null;
                return acc;
            };

            var audioInputRttMilliseconds = statsResult.audio.input.reduce(rttReducer, null);
            var videoInputRttMilliseconds = statsResult.video.input.reduce(rttReducer, null);

            if (audioInputRttMilliseconds !== null) {
                statsResult.audio.output.forEach((stats) => { stats._rttMilliseconds = audioInputRttMilliseconds; });
            }

            if (videoInputRttMilliseconds !== null) {
                statsResult.video.output.forEach((stats) => { stats._rttMilliseconds = videoInputRttMilliseconds; });
            }

            return statsResult;

        } else {
            return Promise.reject(new IllegalState());
        }

    }