2018-04-26 15:33:47 +02:00
|
|
|
/*
|
2020-02-04 11:25:54 +01:00
|
|
|
* (C) Copyright 2017-2020 OpenVidu (https://openvidu.io)
|
2018-04-26 15:33:47 +02:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
// tslint:disable:no-string-literal
|
|
|
|
|
2018-05-08 13:01:34 +02:00
|
|
|
import { Stream } from '../../OpenVidu/Stream';
|
2020-05-04 20:01:56 +02:00
|
|
|
import { OpenViduLogger } from '../Logger/OpenViduLogger';
|
2020-10-13 16:13:37 +02:00
|
|
|
import { PlatformUtils } from '../Utils/Platform';
|
2020-05-04 20:01:56 +02:00
|
|
|
/**
|
|
|
|
* @hidden
|
|
|
|
*/
|
|
|
|
const logger: OpenViduLogger = OpenViduLogger.getInstance();
|
2020-10-13 16:13:37 +02:00
|
|
|
/**
|
|
|
|
* @hidden
|
|
|
|
*/
|
2020-11-26 13:17:55 +01:00
|
|
|
let platform: PlatformUtils;
|
2018-04-26 15:33:47 +02:00
|
|
|
|
2021-02-16 17:17:37 +01:00
|
|
|
interface WebrtcStatsConfig {
|
|
|
|
interval: number,
|
|
|
|
httpEndpoint: string
|
|
|
|
}
|
|
|
|
|
2021-02-24 10:43:23 +01:00
|
|
|
interface JSONStatsResponse {
|
2021-02-16 17:17:37 +01:00
|
|
|
'@timestamp': string,
|
|
|
|
participant_id: string,
|
|
|
|
session_id: string,
|
|
|
|
platform: string,
|
|
|
|
platform_description: string,
|
|
|
|
stream: string,
|
2021-02-24 10:43:23 +01:00
|
|
|
webrtc_stats: IWebrtcStats
|
2021-02-16 17:17:37 +01:00
|
|
|
}
|
|
|
|
|
2021-03-18 13:39:50 +01:00
|
|
|
/**
|
|
|
|
* Common WebRtcSTats for latest Chromium and Firefox versions
|
|
|
|
*/
|
2021-02-24 10:43:23 +01:00
|
|
|
interface IWebrtcStats {
|
2021-03-18 13:39:50 +01:00
|
|
|
inbound?: {
|
2021-02-24 10:43:23 +01:00
|
|
|
audio: {
|
|
|
|
bytesReceived: number,
|
|
|
|
packetsReceived: number,
|
2021-03-05 12:26:03 +01:00
|
|
|
packetsLost: number,
|
2021-03-18 13:39:50 +01:00
|
|
|
jitter: number
|
2021-02-24 10:43:23 +01:00
|
|
|
} | {},
|
|
|
|
video: {
|
|
|
|
bytesReceived: number,
|
|
|
|
packetsReceived: number,
|
|
|
|
packetsLost: number,
|
2021-03-18 13:39:50 +01:00
|
|
|
jitter?: number, // Firefox
|
|
|
|
jitterBufferDelay?: number, // Chrome
|
2021-02-24 10:43:23 +01:00
|
|
|
framesDecoded: number,
|
2021-03-18 13:39:50 +01:00
|
|
|
firCount: number,
|
|
|
|
nackCount: number,
|
|
|
|
pliCount: number,
|
|
|
|
frameHeight?: number, // Chrome
|
|
|
|
frameWidth?: number, // Chrome
|
|
|
|
framesDropped?: number, // Chrome
|
|
|
|
framesReceived?: number // Chrome
|
2021-02-24 10:43:23 +01:00
|
|
|
} | {}
|
2021-03-18 13:39:50 +01:00
|
|
|
},
|
|
|
|
outbound?: {
|
2021-02-24 10:43:23 +01:00
|
|
|
audio: {
|
|
|
|
bytesSent: number,
|
|
|
|
packetsSent: number,
|
|
|
|
} | {},
|
|
|
|
video: {
|
|
|
|
bytesSent: number,
|
|
|
|
packetsSent: number,
|
2021-03-18 13:39:50 +01:00
|
|
|
firCount: number,
|
2021-02-24 10:43:23 +01:00
|
|
|
framesEncoded: number,
|
2021-03-18 13:39:50 +01:00
|
|
|
nackCount: number,
|
|
|
|
pliCount: number,
|
|
|
|
qpSum: number,
|
|
|
|
frameHeight?: number, // Chrome
|
|
|
|
frameWidth?: number, // Chrome
|
|
|
|
framesSent?: number // Chrome
|
2021-02-24 10:43:23 +01:00
|
|
|
} | {}
|
2021-03-18 13:39:50 +01:00
|
|
|
}
|
2021-02-24 10:43:23 +01:00
|
|
|
};
|
|
|
|
|
2018-04-26 15:33:47 +02:00
|
|
|
export class WebRtcStats {
|
|
|
|
|
2021-02-16 17:17:37 +01:00
|
|
|
private readonly STATS_ITEM_NAME = 'webrtc-stats-config';
|
|
|
|
|
2018-04-26 15:33:47 +02:00
|
|
|
private webRtcStatsEnabled = false;
|
|
|
|
private webRtcStatsIntervalId: NodeJS.Timer;
|
|
|
|
private statsInterval = 1;
|
2021-02-16 17:17:37 +01:00
|
|
|
private POST_URL: string;
|
2018-04-26 15:33:47 +02:00
|
|
|
|
2020-11-26 13:17:55 +01:00
|
|
|
constructor(private stream: Stream) {
|
|
|
|
platform = PlatformUtils.getInstance();
|
|
|
|
}
|
2018-04-26 15:33:47 +02:00
|
|
|
|
|
|
|
public isEnabled(): boolean {
|
|
|
|
return this.webRtcStatsEnabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
public initWebRtcStats(): void {
|
|
|
|
|
2021-02-16 17:17:37 +01:00
|
|
|
const webrtcObj = localStorage.getItem(this.STATS_ITEM_NAME);
|
2018-04-26 15:33:47 +02:00
|
|
|
|
2021-02-16 17:17:37 +01:00
|
|
|
if (!!webrtcObj) {
|
2018-04-26 15:33:47 +02:00
|
|
|
this.webRtcStatsEnabled = true;
|
2021-02-16 17:17:37 +01:00
|
|
|
const webrtcStatsConfig: WebrtcStatsConfig = JSON.parse(webrtcObj);
|
|
|
|
// webrtc object found in local storage
|
|
|
|
logger.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId);
|
|
|
|
logger.warn('localStorage item: ' + JSON.stringify(webrtcStatsConfig));
|
2018-04-26 15:33:47 +02:00
|
|
|
|
2021-02-24 10:43:23 +01:00
|
|
|
this.POST_URL = webrtcStatsConfig.httpEndpoint;
|
|
|
|
this.statsInterval = webrtcStatsConfig.interval; // Interval in seconds
|
|
|
|
|
2021-02-16 17:17:37 +01:00
|
|
|
this.webRtcStatsIntervalId = setInterval(async () => {
|
|
|
|
await this.sendStatsToHttpEndpoint();
|
2018-04-26 15:33:47 +02:00
|
|
|
}, this.statsInterval * 1000);
|
|
|
|
|
2021-03-18 13:39:50 +01:00
|
|
|
} else {
|
2021-02-16 17:17:37 +01:00
|
|
|
logger.debug('WebRtc stats not enabled');
|
2018-04-26 15:33:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-20 14:04:09 +01:00
|
|
|
// {
|
|
|
|
// "localCandidate": {
|
|
|
|
// "id": "RTCIceCandidate_/r4P1y2Q",
|
|
|
|
// "timestamp": 1616080155617,
|
|
|
|
// "type": "local-candidate",
|
|
|
|
// "transportId": "RTCTransport_0_1",
|
|
|
|
// "isRemote": false,
|
|
|
|
// "networkType": "wifi",
|
|
|
|
// "ip": "123.45.67.89",
|
|
|
|
// "port": 63340,
|
|
|
|
// "protocol": "udp",
|
|
|
|
// "candidateType": "srflx",
|
|
|
|
// "priority": 1686052607,
|
|
|
|
// "deleted": false,
|
|
|
|
// "raw": [
|
|
|
|
// "candidate:3345412921 1 udp 1686052607 123.45.67.89 63340 typ srflx raddr 192.168.1.31 rport 63340 generation 0 ufrag 0ZtT network-id 1 network-cost 10",
|
|
|
|
// "candidate:58094482 1 udp 41885695 98.76.54.32 44431 typ relay raddr 123.45.67.89 rport 63340 generation 0 ufrag 0ZtT network-id 1 network-cost 10"
|
|
|
|
// ]
|
|
|
|
// },
|
|
|
|
// "remoteCandidate": {
|
|
|
|
// "id": "RTCIceCandidate_1YO18gph",
|
|
|
|
// "timestamp": 1616080155617,
|
|
|
|
// "type": "remote-candidate",
|
|
|
|
// "transportId": "RTCTransport_0_1",
|
|
|
|
// "isRemote": true,
|
|
|
|
// "ip": "12.34.56.78",
|
|
|
|
// "port": 64989,
|
|
|
|
// "protocol": "udp",
|
|
|
|
// "candidateType": "srflx",
|
|
|
|
// "priority": 1679819263,
|
|
|
|
// "deleted": false,
|
|
|
|
// "raw": [
|
|
|
|
// "candidate:16 1 UDP 1679819263 12.34.56.78 64989 typ srflx raddr 172.19.0.1 rport 64989",
|
|
|
|
// "candidate:16 1 UDP 1679819263 12.34.56.78 64989 typ srflx raddr 172.19.0.1 rport 64989"
|
|
|
|
// ]
|
|
|
|
// }
|
|
|
|
// }
|
2021-03-18 13:39:50 +01:00
|
|
|
// Have been tested in:
|
|
|
|
// - Linux Desktop:
|
|
|
|
// - Chrome 89.0.4389.90
|
|
|
|
// - Opera 74.0.3911.218
|
|
|
|
// - Firefox 86
|
|
|
|
// - Microsoft Edge 91.0.825.0
|
|
|
|
// - Electron 11.3.0 (Chromium 87.0.4280.141)
|
|
|
|
// - Windows Desktop:
|
2021-03-20 14:04:09 +01:00
|
|
|
// - Chrome 89.0.4389.90
|
|
|
|
// - Opera 74.0.3911.232
|
|
|
|
// - Firefox 86.0.1
|
|
|
|
// - Microsoft Edge 89.0.774.54
|
|
|
|
// - Electron 11.3.0 (Chromium 87.0.4280.141)
|
2021-03-18 13:39:50 +01:00
|
|
|
// - MacOS Desktop:
|
2021-03-24 22:54:04 +01:00
|
|
|
// - Chrome 89.0.4389.90
|
|
|
|
// - Firefox 87.0
|
|
|
|
// - Opera 75.0.3969.93
|
|
|
|
// - Microsoft Edge 89.0.774.57
|
|
|
|
// - Safari 14.0 (14610.1.28.1.9)
|
|
|
|
// - Electron 11.3.0 (Chromium 87.0.4280.141)
|
2021-03-18 13:39:50 +01:00
|
|
|
// - Android:
|
|
|
|
// - Chrome Mobile 89.0.4389.90
|
|
|
|
// - Opera 62.3.3146.57763
|
|
|
|
// - Firefox Mobile 86.6.1
|
|
|
|
// - Microsoft Edge Mobile 46.02.4.5147
|
|
|
|
// - Ionic 5
|
2021-03-20 14:04:09 +01:00
|
|
|
// - React Native 0.64
|
2021-03-18 13:39:50 +01:00
|
|
|
// - iOS:
|
|
|
|
// - Safari Mobile
|
|
|
|
// - ¿Ionic?
|
|
|
|
// - ¿React Native?
|
2021-02-16 18:16:47 +01:00
|
|
|
public getSelectedIceCandidateInfo(): Promise<any> {
|
2021-03-18 13:39:50 +01:00
|
|
|
return new Promise(async (resolve, reject) => {
|
|
|
|
|
|
|
|
const statsReport: any = await this.stream.getRTCPeerConnection().getStats();
|
|
|
|
let transportStat;
|
|
|
|
const candidatePairs: Map<string, any> = new Map();
|
|
|
|
const localCandidates: Map<string, any> = new Map();
|
|
|
|
const remoteCandidates: Map<string, any> = new Map();
|
|
|
|
statsReport.forEach((stat: any) => {
|
2021-03-24 22:54:04 +01:00
|
|
|
if (stat.type === 'transport' && (platform.isChromium() || platform.isSafariBrowser() || platform.isReactNative())) {
|
2021-03-18 13:39:50 +01:00
|
|
|
transportStat = stat;
|
|
|
|
}
|
|
|
|
switch (stat.type) {
|
|
|
|
case 'candidate-pair':
|
|
|
|
candidatePairs.set(stat.id, stat);
|
|
|
|
break;
|
|
|
|
case 'local-candidate':
|
|
|
|
localCandidates.set(stat.id, stat);
|
|
|
|
break;
|
|
|
|
case 'remote-candidate':
|
|
|
|
remoteCandidates.set(stat.id, stat);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let selectedCandidatePair;
|
2021-03-20 14:07:38 +01:00
|
|
|
if (transportStat != null) {
|
2021-03-18 13:39:50 +01:00
|
|
|
const selectedCandidatePairId = transportStat.selectedCandidatePairId
|
|
|
|
selectedCandidatePair = candidatePairs.get(selectedCandidatePairId);
|
|
|
|
} else {
|
2021-03-24 22:54:04 +01:00
|
|
|
// This is basically Firefox
|
2021-03-18 13:39:50 +01:00
|
|
|
const length = candidatePairs.size;
|
|
|
|
const iterator = candidatePairs.values();
|
|
|
|
for (let i = 0; i < length; i++) {
|
|
|
|
const candidatePair = iterator.next().value;
|
|
|
|
if (candidatePair['selected']) {
|
|
|
|
selectedCandidatePair = candidatePair;
|
|
|
|
break;
|
2021-02-16 18:16:47 +01:00
|
|
|
}
|
2021-03-18 13:39:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
const localCandidateId = selectedCandidatePair.localCandidateId;
|
|
|
|
const remoteCandidateId = selectedCandidatePair.remoteCandidateId;
|
|
|
|
let finalLocalCandidate = localCandidates.get(localCandidateId);
|
|
|
|
if (!!finalLocalCandidate) {
|
|
|
|
const candList = this.stream.getLocalIceCandidateList();
|
|
|
|
const cand = candList.filter((c: RTCIceCandidate) => {
|
|
|
|
return (!!c.candidate &&
|
|
|
|
(c.candidate.indexOf(finalLocalCandidate.ip) >= 0 || c.candidate.indexOf(finalLocalCandidate.address) >= 0) &&
|
2021-03-20 14:04:09 +01:00
|
|
|
c.candidate.indexOf(finalLocalCandidate.port) >= 0);
|
2021-02-16 18:16:47 +01:00
|
|
|
});
|
2021-03-18 13:39:50 +01:00
|
|
|
finalLocalCandidate.raw = [];
|
|
|
|
for (let c of cand) {
|
|
|
|
finalLocalCandidate.raw.push(c.candidate);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
finalLocalCandidate = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used';
|
|
|
|
}
|
|
|
|
|
|
|
|
let finalRemoteCandidate = remoteCandidates.get(remoteCandidateId);
|
|
|
|
if (!!finalRemoteCandidate) {
|
|
|
|
const candList = this.stream.getRemoteIceCandidateList();
|
|
|
|
const cand = candList.filter((c: RTCIceCandidate) => {
|
|
|
|
return (!!c.candidate &&
|
|
|
|
(c.candidate.indexOf(finalRemoteCandidate.ip) >= 0 || c.candidate.indexOf(finalRemoteCandidate.address) >= 0) &&
|
|
|
|
c.candidate.indexOf(finalRemoteCandidate.port) >= 0);
|
|
|
|
});
|
|
|
|
finalRemoteCandidate.raw = [];
|
|
|
|
for (let c of cand) {
|
|
|
|
finalRemoteCandidate.raw.push(c.candidate);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
finalRemoteCandidate = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used';
|
|
|
|
}
|
|
|
|
|
|
|
|
resolve({
|
|
|
|
localCandidate: finalLocalCandidate,
|
|
|
|
remoteCandidate: finalRemoteCandidate
|
|
|
|
});
|
2021-02-16 18:16:47 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-04-26 15:33:47 +02:00
|
|
|
public stopWebRtcStats() {
|
|
|
|
if (this.webRtcStatsEnabled) {
|
|
|
|
clearInterval(this.webRtcStatsIntervalId);
|
2020-05-04 20:01:56 +02:00
|
|
|
logger.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId);
|
2018-04-26 15:33:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-24 10:43:23 +01:00
|
|
|
private async sendStats(url: string, response: JSONStatsResponse): Promise<void> {
|
2021-02-16 17:17:37 +01:00
|
|
|
try {
|
|
|
|
const configuration: RequestInit = {
|
|
|
|
headers: {
|
|
|
|
'Content-type': 'application/json'
|
2018-06-11 13:19:52 +02:00
|
|
|
},
|
2021-02-24 10:43:23 +01:00
|
|
|
body: JSON.stringify(response),
|
2021-02-16 17:17:37 +01:00
|
|
|
method: 'POST',
|
2018-04-26 15:33:47 +02:00
|
|
|
};
|
2021-02-16 17:17:37 +01:00
|
|
|
await fetch(url, configuration);
|
2018-04-26 15:33:47 +02:00
|
|
|
|
2021-02-16 17:17:37 +01:00
|
|
|
} catch (error) {
|
|
|
|
logger.error(error);
|
|
|
|
}
|
|
|
|
}
|
2018-04-26 15:33:47 +02:00
|
|
|
|
2021-02-16 17:17:37 +01:00
|
|
|
private async sendStatsToHttpEndpoint(): Promise<void> {
|
|
|
|
try {
|
2021-03-18 13:39:50 +01:00
|
|
|
const webrtcStats: IWebrtcStats = await this.getCommonStats();
|
2021-02-24 10:43:23 +01:00
|
|
|
const response = this.generateJSONStatsResponse(webrtcStats);
|
|
|
|
await this.sendStats(this.POST_URL, response);
|
2021-02-16 17:17:37 +01:00
|
|
|
} catch (error) {
|
|
|
|
logger.log(error);
|
|
|
|
}
|
|
|
|
}
|
2018-04-26 15:33:47 +02:00
|
|
|
|
2021-03-20 14:04:09 +01:00
|
|
|
// Have been tested in:
|
|
|
|
// - Linux Desktop:
|
|
|
|
// - Chrome 89.0.4389.90
|
|
|
|
// - Opera 74.0.3911.218
|
|
|
|
// - Firefox 86
|
|
|
|
// - Microsoft Edge 91.0.825.0
|
|
|
|
// - Electron 11.3.0 (Chromium 87.0.4280.141)
|
|
|
|
// - Windows Desktop:
|
|
|
|
// - Chrome 89.0.4389.90
|
|
|
|
// - Opera 74.0.3911.232
|
|
|
|
// - Firefox 86.0.1
|
|
|
|
// - Microsoft Edge 89.0.774.54
|
|
|
|
// - Electron 11.3.0 (Chromium 87.0.4280.141)
|
|
|
|
// - MacOS Desktop:
|
2021-05-19 10:46:43 +02:00
|
|
|
// - Chrome 89.0.4389.90
|
|
|
|
// - Opera 75.0.3969.93
|
|
|
|
// - Firefox 87.0
|
|
|
|
// - Microsoft Edge 89.0.774.57
|
|
|
|
// - Safari 14.0 (14610.1.28.1.9)
|
|
|
|
// - Electron 11.3.0 (Chromium 87.0.4280.141)
|
2021-03-20 14:04:09 +01:00
|
|
|
// - Android:
|
|
|
|
// - Chrome Mobile 89.0.4389.90
|
|
|
|
// - Opera 62.3.3146.57763
|
|
|
|
// - Firefox Mobile 86.6.1
|
|
|
|
// - Microsoft Edge Mobile 46.02.4.5147
|
|
|
|
// - Ionic 5
|
|
|
|
// - React Native 0.64
|
|
|
|
// - iOS:
|
|
|
|
// - Safari Mobile
|
|
|
|
// - ¿Ionic?
|
|
|
|
// - ¿React Native?
|
2021-03-18 13:39:50 +01:00
|
|
|
public async getCommonStats(): Promise<IWebrtcStats> {
|
2018-04-26 15:33:47 +02:00
|
|
|
|
2021-02-16 17:17:37 +01:00
|
|
|
return new Promise(async (resolve, reject) => {
|
2021-02-24 10:43:23 +01:00
|
|
|
|
2021-03-18 13:39:50 +01:00
|
|
|
const statsReport: any = await this.stream.getRTCPeerConnection().getStats();
|
|
|
|
const response = this.getWebRtcStatsResponseOutline();
|
2021-03-24 22:54:04 +01:00
|
|
|
const videoTrackStats = ['framesReceived', 'framesDropped', 'framesSent', 'frameHeight', 'frameWidth'];
|
2021-02-24 10:43:23 +01:00
|
|
|
|
2021-03-18 13:39:50 +01:00
|
|
|
statsReport.forEach((stat: any) => {
|
2018-04-26 15:33:47 +02:00
|
|
|
|
2021-03-24 22:54:04 +01:00
|
|
|
let mediaType = stat.mediaType != null ? stat.mediaType : stat.kind;
|
2021-03-18 13:39:50 +01:00
|
|
|
const addStat = (direction: string, key: string): void => {
|
|
|
|
if (stat[key] != null && response[direction] != null) {
|
2021-03-24 22:54:04 +01:00
|
|
|
if (!mediaType && (videoTrackStats.indexOf(key) > -1)) {
|
|
|
|
mediaType = 'video';
|
|
|
|
}
|
|
|
|
if (direction != null && mediaType != null && key != null && response[direction] != null && response[direction][mediaType] != null) {
|
|
|
|
response[direction][mediaType][key] = Number(stat[key]);
|
|
|
|
}
|
2021-03-18 13:39:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (stat.type) {
|
|
|
|
case "outbound-rtp":
|
|
|
|
addStat('outbound', 'bytesSent');
|
|
|
|
addStat('outbound', 'packetsSent');
|
|
|
|
addStat('outbound', 'framesEncoded');
|
|
|
|
addStat('outbound', 'nackCount');
|
|
|
|
addStat('outbound', 'firCount');
|
|
|
|
addStat('outbound', 'pliCount');
|
|
|
|
addStat('outbound', 'qpSum');
|
|
|
|
break;
|
|
|
|
case "inbound-rtp":
|
|
|
|
addStat('inbound', 'bytesReceived');
|
|
|
|
addStat('inbound', 'packetsReceived');
|
|
|
|
addStat('inbound', 'packetsLost');
|
|
|
|
addStat('inbound', 'jitter');
|
|
|
|
addStat('inbound', 'framesDecoded');
|
|
|
|
addStat('inbound', 'nackCount');
|
|
|
|
addStat('inbound', 'firCount');
|
|
|
|
addStat('inbound', 'pliCount');
|
|
|
|
break;
|
|
|
|
case 'track':
|
|
|
|
addStat('inbound', 'jitterBufferDelay');
|
|
|
|
addStat('inbound', 'framesReceived');
|
|
|
|
addStat('outbound', 'framesDropped');
|
|
|
|
addStat('outbound', 'framesSent');
|
|
|
|
addStat(this.stream.isLocal() ? 'outbound' : 'inbound', 'frameHeight');
|
|
|
|
addStat(this.stream.isLocal() ? 'outbound' : 'inbound', 'frameWidth');
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return resolve(response);
|
2021-02-16 17:17:37 +01:00
|
|
|
});
|
|
|
|
}
|
2018-04-26 15:33:47 +02:00
|
|
|
|
2021-02-24 10:43:23 +01:00
|
|
|
private generateJSONStatsResponse(stats: IWebrtcStats): JSONStatsResponse {
|
2021-02-16 17:17:37 +01:00
|
|
|
return {
|
|
|
|
'@timestamp': new Date().toISOString(),
|
|
|
|
participant_id: this.stream.connection.data,
|
|
|
|
session_id: this.stream.session.sessionId,
|
|
|
|
platform: platform.getName(),
|
|
|
|
platform_description: platform.getDescription(),
|
|
|
|
stream: 'webRTC',
|
|
|
|
webrtc_stats: stats
|
2018-04-26 15:33:47 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-03-18 13:39:50 +01:00
|
|
|
private getWebRtcStatsResponseOutline(): IWebrtcStats {
|
|
|
|
if (this.stream.isLocal()) {
|
|
|
|
return {
|
|
|
|
outbound: {
|
|
|
|
audio: {},
|
|
|
|
video: {}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
return {
|
|
|
|
inbound: {
|
|
|
|
audio: {},
|
|
|
|
video: {}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2018-04-26 15:33:47 +02:00
|
|
|
}
|
2021-02-24 10:43:23 +01:00
|
|
|
|
2018-04-26 15:33:47 +02:00
|
|
|
}
|