mirror of https://github.com/OpenVidu/openvidu.git
'videoElementDestroyed' event for Subscriber and Publisher. WebRtc stats for ElasTest. es5 to es6. webrtc-adapter to 6.1.1
parent
4cab8a74a0
commit
33e29b26c3
|
@ -8,7 +8,7 @@
|
||||||
"sdp-translator": "0.1.24",
|
"sdp-translator": "0.1.24",
|
||||||
"ua-parser-js": "0.7.17",
|
"ua-parser-js": "0.7.17",
|
||||||
"uuid": "3.1.0",
|
"uuid": "3.1.0",
|
||||||
"webrtc-adapter": "6.0.4",
|
"webrtc-adapter": "6.1.1",
|
||||||
"wolfy87-eventemitter": "5.2.4"
|
"wolfy87-eventemitter": "5.2.4"
|
||||||
},
|
},
|
||||||
"description": "OpenVidu Browser",
|
"description": "OpenVidu Browser",
|
||||||
|
|
|
@ -27,7 +27,11 @@ export class Publisher {
|
||||||
|
|
||||||
// Listens to the deactivation of the default behaviour upon the deletion of a Stream object
|
// Listens to the deactivation of the default behaviour upon the deletion of a Stream object
|
||||||
this.ee.addListener('stream-destroyed-default', event => {
|
this.ee.addListener('stream-destroyed-default', event => {
|
||||||
event.stream.removeVideo();
|
let s: Stream = event.stream;
|
||||||
|
s.addOnceEventListener('video-removed', () => {
|
||||||
|
this.ee.emitEvent('videoElementDestroyed');
|
||||||
|
});
|
||||||
|
s.removeVideo();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (document.getElementById(parentId) != null) {
|
if (document.getElementById(parentId) != null) {
|
||||||
|
|
|
@ -15,6 +15,11 @@ export class Subscriber {
|
||||||
if (document.getElementById(parentId) != null) {
|
if (document.getElementById(parentId) != null) {
|
||||||
this.element = document.getElementById(parentId)!!;
|
this.element = document.getElementById(parentId)!!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Listens to deletion of the HTML video element of the Subscriber
|
||||||
|
this.stream.addEventListener('video-removed', () => {
|
||||||
|
this.ee.emitEvent('videoElementDestroyed');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
on(eventName: string, callback) {
|
on(eventName: string, callback) {
|
||||||
|
@ -33,7 +38,6 @@ export class Subscriber {
|
||||||
}]);
|
}]);
|
||||||
} else {
|
} else {
|
||||||
this.stream.addOnceEventListener('video-element-created-by-stream', element => {
|
this.stream.addOnceEventListener('video-element-created-by-stream', element => {
|
||||||
console.warn("Subscriber emitting videoElementCreated");
|
|
||||||
this.id = element.id;
|
this.id = element.id;
|
||||||
this.ee.emitEvent('videoElementCreated', [{
|
this.ee.emitEvent('videoElementCreated', [{
|
||||||
element: element
|
element: element
|
||||||
|
|
|
@ -236,7 +236,7 @@ export class OpenViduInternal {
|
||||||
if (this.session !== undefined && this.session instanceof SessionInternal) {
|
if (this.session !== undefined && this.session instanceof SessionInternal) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
console.warn('Room instance not found');
|
console.warn('Session instance not found');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -472,21 +472,21 @@ export class SessionInternal {
|
||||||
|
|
||||||
onRoomClosed(msg) {
|
onRoomClosed(msg) {
|
||||||
|
|
||||||
console.info("Room closed: " + JSON.stringify(msg));
|
console.info("Session closed: " + JSON.stringify(msg));
|
||||||
let room = msg.room;
|
let room = msg.room;
|
||||||
if (room !== undefined) {
|
if (room !== undefined) {
|
||||||
this.ee.emitEvent('room-closed', [{
|
this.ee.emitEvent('room-closed', [{
|
||||||
room: room
|
room: room
|
||||||
}]);
|
}]);
|
||||||
} else {
|
} else {
|
||||||
console.warn("Room undefined in on room closed", msg);
|
console.warn("Session undefined on session closed", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onLostConnection() {
|
onLostConnection() {
|
||||||
|
|
||||||
if (!this.connected) {
|
if (!this.connected) {
|
||||||
console.warn('Not connected to room: if you are not debugging, this is probably a certificate error');
|
console.warn('Not connected to session: if you are not debugging, this is probably a certificate error');
|
||||||
if (window.confirm('If you are not debugging, this is probably a certificate error at \"' + this.openVidu.getOpenViduServerURL() + '\"\n\nClick OK to navigate and accept it')) {
|
if (window.confirm('If you are not debugging, this is probably a certificate error at \"' + this.openVidu.getOpenViduServerURL() + '\"\n\nClick OK to navigate and accept it')) {
|
||||||
location.assign(this.openVidu.getOpenViduServerURL() + '/accept-certificate');
|
location.assign(this.openVidu.getOpenViduServerURL() + '/accept-certificate');
|
||||||
};
|
};
|
||||||
|
@ -498,7 +498,7 @@ export class SessionInternal {
|
||||||
if (room !== undefined) {
|
if (room !== undefined) {
|
||||||
this.ee.emitEvent('lost-connection', [{ room }]);
|
this.ee.emitEvent('lost-connection', [{ room }]);
|
||||||
} else {
|
} else {
|
||||||
console.warn('Room undefined when lost connection');
|
console.warn('Session undefined when lost connection');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,12 @@ import { Connection } from './Connection';
|
||||||
import { SessionInternal } from './SessionInternal';
|
import { SessionInternal } from './SessionInternal';
|
||||||
import { OpenViduInternal, Callback } from './OpenViduInternal';
|
import { OpenViduInternal, Callback } from './OpenViduInternal';
|
||||||
import { OpenViduError, OpenViduErrorName } from './OpenViduError';
|
import { OpenViduError, OpenViduErrorName } from './OpenViduError';
|
||||||
|
import { WebRtcStats } from './WebRtcStats';
|
||||||
import EventEmitter = require('wolfy87-eventemitter');
|
import EventEmitter = require('wolfy87-eventemitter');
|
||||||
import * as kurentoUtils from '../KurentoUtils/kurento-utils-js';
|
import * as kurentoUtils from '../KurentoUtils/kurento-utils-js';
|
||||||
|
|
||||||
import * as adapter from 'webrtc-adapter';
|
import * as adapter from 'webrtc-adapter';
|
||||||
|
|
||||||
declare var navigator: any;
|
declare var navigator: any;
|
||||||
declare var RTCSessionDescription: any;
|
declare var RTCSessionDescription: any;
|
||||||
|
|
||||||
|
@ -87,6 +89,8 @@ export class Stream {
|
||||||
public isScreenRequestedReady: boolean = false;
|
public isScreenRequestedReady: boolean = false;
|
||||||
private isScreenRequested = false;
|
private isScreenRequested = false;
|
||||||
|
|
||||||
|
private webRtcStats: WebRtcStats;
|
||||||
|
|
||||||
constructor(private openVidu: OpenViduInternal, private local: boolean, private room: SessionInternal, options: any) {
|
constructor(private openVidu: OpenViduInternal, private local: boolean, private room: SessionInternal, options: any) {
|
||||||
if (options !== 'screen-options') {
|
if (options !== 'screen-options') {
|
||||||
if ('id' in options) {
|
if ('id' in options) {
|
||||||
|
@ -120,12 +124,14 @@ export class Stream {
|
||||||
if (this.video) {
|
if (this.video) {
|
||||||
if (typeof parentElement === "string") {
|
if (typeof parentElement === "string") {
|
||||||
document.getElementById(parentElement)!.removeChild(this.video);
|
document.getElementById(parentElement)!.removeChild(this.video);
|
||||||
|
this.ee.emitEvent('video-removed');
|
||||||
} else if (parentElement instanceof Element) {
|
} else if (parentElement instanceof Element) {
|
||||||
parentElement.removeChild(this.video);
|
parentElement.removeChild(this.video);
|
||||||
}
|
this.ee.emitEvent('video-removed');
|
||||||
else if (!parentElement) {
|
} else if (!parentElement) {
|
||||||
if (document.getElementById(this.parentId)) {
|
if (document.getElementById(this.parentId)) {
|
||||||
document.getElementById(this.parentId)!.removeChild(this.video);
|
document.getElementById(this.parentId)!.removeChild(this.video);
|
||||||
|
this.ee.emitEvent('video-removed');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete this.video;
|
delete this.video;
|
||||||
|
@ -225,6 +231,10 @@ export class Stream {
|
||||||
return this.wp;
|
return this.wp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getRTCPeerConnection() {
|
||||||
|
return this.wp.peerConnection;
|
||||||
|
}
|
||||||
|
|
||||||
addEventListener(eventName: string, listener: any) {
|
addEventListener(eventName: string, listener: any) {
|
||||||
this.ee.addListener(eventName, listener);
|
this.ee.addListener(eventName, listener);
|
||||||
}
|
}
|
||||||
|
@ -324,10 +334,6 @@ export class Stream {
|
||||||
return this.connection;
|
return this.connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRTCPeerConnection() {
|
|
||||||
return this.getWebRtcPeer().peerConnection;
|
|
||||||
}
|
|
||||||
|
|
||||||
requestCameraAccess(callback: Callback<Stream>) {
|
requestCameraAccess(callback: Callback<Stream>) {
|
||||||
|
|
||||||
this.connection.addStream(this);
|
this.connection.addStream(this);
|
||||||
|
@ -614,6 +620,9 @@ export class Stream {
|
||||||
stream: this
|
stream: this
|
||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.initWebRtcStats();
|
||||||
|
|
||||||
}, error => {
|
}, error => {
|
||||||
console.error(this.streamId + ": Error setting SDP to the peer connection: "
|
console.error(this.streamId + ": Error setting SDP to the peer connection: "
|
||||||
+ JSON.stringify(error));
|
+ JSON.stringify(error));
|
||||||
|
@ -668,6 +677,8 @@ export class Stream {
|
||||||
this.speechEvent.stop();
|
this.speechEvent.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.stopWebRtcStats();
|
||||||
|
|
||||||
console.info((this.local ? "Local " : "Remote ") + "'Stream' with id [" + this.streamId + "]' has been succesfully disposed");
|
console.info((this.local ? "Local " : "Remote ") + "'Stream' with id [" + this.streamId + "]' has been succesfully disposed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,4 +686,16 @@ export class Stream {
|
||||||
this.outboundOptions = options;
|
this.outboundOptions = options;
|
||||||
this.streamId = "SCREEN";
|
this.streamId = "SCREEN";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private initWebRtcStats(): void {
|
||||||
|
this.webRtcStats = new WebRtcStats(this);
|
||||||
|
this.webRtcStats.initWebRtcStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
private stopWebRtcStats() {
|
||||||
|
if (this.webRtcStats.isEnabled()) {
|
||||||
|
this.webRtcStats.stopWebRtcStats();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,321 @@
|
||||||
|
import { Stream } from './Stream';
|
||||||
|
import * as adapter from 'webrtc-adapter';
|
||||||
|
|
||||||
|
export class WebRtcStats {
|
||||||
|
|
||||||
|
private webRtcStatsEnabled: boolean = false;
|
||||||
|
private webRtcStatsIntervalId: number;
|
||||||
|
private statsInterval: number = 1;
|
||||||
|
private stats: any = {
|
||||||
|
"inbound": {
|
||||||
|
"audio": {
|
||||||
|
"bytesReceived": 0,
|
||||||
|
"packetsReceived": 0,
|
||||||
|
"packetsLost": 0
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"bytesReceived": 0,
|
||||||
|
"packetsReceived": 0,
|
||||||
|
"packetsLost": 0,
|
||||||
|
"framesDecoded": 0,
|
||||||
|
"nackCount": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"outbound": {
|
||||||
|
"audio": {
|
||||||
|
"bytesSent": 0,
|
||||||
|
"packetsSent": 0,
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"bytesSent": 0,
|
||||||
|
"packetsSent": 0,
|
||||||
|
"framesEncoded": 0,
|
||||||
|
"nackCount": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(private stream: Stream) { }
|
||||||
|
|
||||||
|
public isEnabled(): boolean {
|
||||||
|
return this.webRtcStatsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public initWebRtcStats(): void {
|
||||||
|
|
||||||
|
let elastestInstrumentation = localStorage.getItem('elastest-instrumentation');
|
||||||
|
|
||||||
|
if (elastestInstrumentation) {
|
||||||
|
// ElasTest instrumentation object found in local storage
|
||||||
|
|
||||||
|
console.warn("WebRtc stats enabled for stream " + this.stream.streamId + " of connection " + this.stream.connection.connectionId);
|
||||||
|
|
||||||
|
this.webRtcStatsEnabled = true;
|
||||||
|
|
||||||
|
let instrumentation = JSON.parse(elastestInstrumentation);
|
||||||
|
this.statsInterval = instrumentation.webrtc.interval; // Interval in seconds
|
||||||
|
|
||||||
|
console.warn("localStorage item: " + JSON.stringify(instrumentation));
|
||||||
|
|
||||||
|
this.webRtcStatsIntervalId = setInterval(() => {
|
||||||
|
this.sendStatsToHttpEndpoint(instrumentation);
|
||||||
|
}, this.statsInterval * 1000);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.debug("WebRtc stats not enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
public stopWebRtcStats() {
|
||||||
|
if (this.webRtcStatsEnabled) {
|
||||||
|
clearInterval(this.webRtcStatsIntervalId);
|
||||||
|
console.warn("WebRtc stats stopped for disposed stream " + this.stream.streamId + " of connection " + this.stream.connection.connectionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sendStatsToHttpEndpoint(instrumentation): void {
|
||||||
|
|
||||||
|
let sendPost = (json) => {
|
||||||
|
let http: XMLHttpRequest = new XMLHttpRequest();
|
||||||
|
let url: string = instrumentation.webrtc.httpEndpoint;
|
||||||
|
http.open("POST", url, true);
|
||||||
|
|
||||||
|
http.setRequestHeader("Content-type", "application/json");
|
||||||
|
|
||||||
|
http.onreadystatechange = () => { // Call a function when the state changes.
|
||||||
|
if (http.readyState == 4 && http.status == 200) {
|
||||||
|
console.log("WebRtc stats succesfully sent to " + url + " for stream " + this.stream.streamId + " of connection " + this.stream.connection.connectionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
http.send(JSON.stringify(json));
|
||||||
|
}
|
||||||
|
|
||||||
|
let f = (stats) => {
|
||||||
|
|
||||||
|
if (adapter.browserDetails.browser === 'firefox') {
|
||||||
|
stats.forEach((stat) => {
|
||||||
|
|
||||||
|
let json = {};
|
||||||
|
|
||||||
|
if ((stat.type === 'inbound-rtp') &&
|
||||||
|
(
|
||||||
|
// Avoid firefox empty outbound-rtp statistics
|
||||||
|
stat.nackCount != null &&
|
||||||
|
stat.isRemote === false &&
|
||||||
|
stat.id.startsWith('inbound') &&
|
||||||
|
stat.remoteId.startsWith('inbound')
|
||||||
|
)) {
|
||||||
|
|
||||||
|
let metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc;
|
||||||
|
let jitter = stat.jitter * 1000;
|
||||||
|
|
||||||
|
let metrics = {
|
||||||
|
"bytesReceived": (stat.bytesReceived - this.stats.inbound[stat.mediaType].bytesReceived) / this.statsInterval,
|
||||||
|
"jitter": jitter,
|
||||||
|
"packetsReceived": (stat.packetsReceived - this.stats.inbound[stat.mediaType].packetsReceived) / this.statsInterval,
|
||||||
|
"packetsLost": (stat.packetsLost - this.stats.inbound[stat.mediaType].packetsLost) / this.statsInterval
|
||||||
|
};
|
||||||
|
let units = {
|
||||||
|
"bytesReceived": "bytes",
|
||||||
|
"jitter": "ms",
|
||||||
|
"packetsReceived": "packets",
|
||||||
|
"packetsLost": "packets"
|
||||||
|
};
|
||||||
|
if (stat.mediaType === 'video') {
|
||||||
|
metrics['framesDecoded'] = (stat.framesDecoded - this.stats.inbound.video.framesDecoded) / this.statsInterval;
|
||||||
|
metrics['nackCount'] = (stat.nackCount - this.stats.inbound.video.nackCount) / this.statsInterval;
|
||||||
|
units['framesDecoded'] = "frames";
|
||||||
|
units['nackCount'] = "packets";
|
||||||
|
|
||||||
|
this.stats.inbound.video.framesDecoded = stat.framesDecoded;
|
||||||
|
this.stats.inbound.video.nackCount = stat.nackCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived;
|
||||||
|
this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived;
|
||||||
|
this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost;
|
||||||
|
|
||||||
|
json = {
|
||||||
|
"@timestamp": new Date(stat.timestamp).toISOString(),
|
||||||
|
"exec": instrumentation.exec,
|
||||||
|
"component": instrumentation.component,
|
||||||
|
"type": metricId,
|
||||||
|
"stream_type": "composed_metric",
|
||||||
|
"units": units
|
||||||
|
}
|
||||||
|
json[metricId] = metrics;
|
||||||
|
|
||||||
|
sendPost(JSON.stringify(json));
|
||||||
|
|
||||||
|
} else if ((stat.type === 'outbound-rtp') &&
|
||||||
|
(
|
||||||
|
// Avoid firefox empty inbound-rtp statistics
|
||||||
|
stat.isRemote === false &&
|
||||||
|
stat.id.toLowerCase().includes('outbound')
|
||||||
|
)) {
|
||||||
|
|
||||||
|
let metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc;
|
||||||
|
|
||||||
|
let metrics = {
|
||||||
|
"bytesSent": (stat.bytesSent - this.stats.outbound[stat.mediaType].bytesSent) / this.statsInterval,
|
||||||
|
"packetsSent": (stat.packetsSent - this.stats.outbound[stat.mediaType].packetsSent) / this.statsInterval
|
||||||
|
};
|
||||||
|
let units = {
|
||||||
|
"bytesSent": "bytes",
|
||||||
|
"packetsSent": "packets"
|
||||||
|
};
|
||||||
|
if (stat.mediaType === 'video') {
|
||||||
|
metrics['framesEncoded'] = (stat.framesEncoded - this.stats.outbound.video.framesEncoded) / this.statsInterval;
|
||||||
|
units['framesEncoded'] = "frames";
|
||||||
|
|
||||||
|
this.stats.outbound.video.framesEncoded = stat.framesEncoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent;
|
||||||
|
this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent;
|
||||||
|
|
||||||
|
json = {
|
||||||
|
"@timestamp": new Date(stat.timestamp).toISOString(),
|
||||||
|
"exec": instrumentation.exec,
|
||||||
|
"component": instrumentation.component,
|
||||||
|
"type": metricId,
|
||||||
|
"stream_type": "composed_metric",
|
||||||
|
"units": units
|
||||||
|
}
|
||||||
|
json[metricId] = metrics;
|
||||||
|
|
||||||
|
sendPost(JSON.stringify(json));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (adapter.browserDetails.browser === 'chrome') {
|
||||||
|
for (let key of Object.keys(stats)) {
|
||||||
|
let stat = stats[key];
|
||||||
|
if (stat.type === 'ssrc') {
|
||||||
|
|
||||||
|
let json = {};
|
||||||
|
|
||||||
|
if ('bytesReceived' in stat && (
|
||||||
|
(stat.mediaType === 'audio' && 'audioOutputLevel' in stat) ||
|
||||||
|
(stat.mediaType === 'video' && 'qpSum' in stat)
|
||||||
|
)) {
|
||||||
|
// inbound-rtp
|
||||||
|
let metricId = 'webrtc_inbound_' + stat.mediaType + '_' + stat.ssrc;
|
||||||
|
|
||||||
|
let metrics = {
|
||||||
|
"bytesReceived": (stat.bytesReceived - this.stats.inbound[stat.mediaType].bytesReceived) / this.statsInterval,
|
||||||
|
"jitter": stat.googJitterBufferMs,
|
||||||
|
"packetsReceived": (stat.packetsReceived - this.stats.inbound[stat.mediaType].packetsReceived) / this.statsInterval,
|
||||||
|
"packetsLost": (stat.packetsLost - this.stats.inbound[stat.mediaType].packetsLost) / this.statsInterval
|
||||||
|
};
|
||||||
|
let units = {
|
||||||
|
"bytesReceived": "bytes",
|
||||||
|
"jitter": "ms",
|
||||||
|
"packetsReceived": "packets",
|
||||||
|
"packetsLost": "packets"
|
||||||
|
};
|
||||||
|
if (stat.mediaType === 'video') {
|
||||||
|
metrics['framesDecoded'] = (stat.framesDecoded - this.stats.inbound.video.framesDecoded) / this.statsInterval;
|
||||||
|
metrics['nackCount'] = (stat.googNacksSent - this.stats.inbound.video.nackCount) / this.statsInterval;
|
||||||
|
units['framesDecoded'] = "frames";
|
||||||
|
units['nackCount'] = "packets";
|
||||||
|
|
||||||
|
this.stats.inbound.video.framesDecoded = stat.framesDecoded;
|
||||||
|
this.stats.inbound.video.nackCount = stat.googNacksSent;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stats.inbound[stat.mediaType].bytesReceived = stat.bytesReceived;
|
||||||
|
this.stats.inbound[stat.mediaType].packetsReceived = stat.packetsReceived;
|
||||||
|
this.stats.inbound[stat.mediaType].packetsLost = stat.packetsLost;
|
||||||
|
|
||||||
|
json = {
|
||||||
|
"@timestamp": new Date(stat.timestamp).toISOString(),
|
||||||
|
"exec": instrumentation.exec,
|
||||||
|
"component": instrumentation.component,
|
||||||
|
"type": metricId,
|
||||||
|
"stream_type": "composed_metric",
|
||||||
|
"units": units
|
||||||
|
}
|
||||||
|
json[metricId] = metrics;
|
||||||
|
|
||||||
|
sendPost(JSON.stringify(json));
|
||||||
|
} else if ('bytesSent' in stat) {
|
||||||
|
// outbound-rtp
|
||||||
|
let metricId = 'webrtc_outbound_' + stat.mediaType + '_' + stat.ssrc;
|
||||||
|
|
||||||
|
let metrics = {
|
||||||
|
"bytesSent": (stat.bytesSent - this.stats.outbound[stat.mediaType].bytesSent) / this.statsInterval,
|
||||||
|
"packetsSent": (stat.packetsSent - this.stats.outbound[stat.mediaType].packetsSent) / this.statsInterval
|
||||||
|
};
|
||||||
|
let units = {
|
||||||
|
"bytesSent": "bytes",
|
||||||
|
"packetsSent": "packets"
|
||||||
|
};
|
||||||
|
if (stat.mediaType === 'video') {
|
||||||
|
metrics['framesEncoded'] = (stat.framesEncoded - this.stats.outbound.video.framesEncoded) / this.statsInterval;
|
||||||
|
units['framesEncoded'] = "frames";
|
||||||
|
|
||||||
|
this.stats.outbound.video.framesEncoded = stat.framesEncoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stats.outbound[stat.mediaType].bytesSent = stat.bytesSent;
|
||||||
|
this.stats.outbound[stat.mediaType].packetsSent = stat.packetsSent;
|
||||||
|
|
||||||
|
json = {
|
||||||
|
"@timestamp": new Date(stat.timestamp).toISOString(),
|
||||||
|
"exec": instrumentation.exec,
|
||||||
|
"component": instrumentation.component,
|
||||||
|
"type": metricId,
|
||||||
|
"stream_type": "composed_metric",
|
||||||
|
"units": units
|
||||||
|
}
|
||||||
|
json[metricId] = metrics;
|
||||||
|
|
||||||
|
sendPost(JSON.stringify(json));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getStatsAgnostic(this.stream.getRTCPeerConnection(), null, f, (error) => { console.log(error) });
|
||||||
|
}
|
||||||
|
|
||||||
|
private standardizeReport(response) {
|
||||||
|
if (adapter.browserDetails.browser === 'firefox') {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
var standardReport = {};
|
||||||
|
response.result().forEach(function (report) {
|
||||||
|
var standardStats = {
|
||||||
|
id: report.id,
|
||||||
|
timestamp: report.timestamp,
|
||||||
|
type: report.type
|
||||||
|
};
|
||||||
|
report.names().forEach(function (name) {
|
||||||
|
standardStats[name] = report.stat(name);
|
||||||
|
});
|
||||||
|
standardReport[standardStats.id] = standardStats;
|
||||||
|
});
|
||||||
|
|
||||||
|
return standardReport;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getStatsAgnostic(pc, selector, successCb, failureCb) {
|
||||||
|
if (adapter.browserDetails.browser === 'firefox') {
|
||||||
|
// getStats takes args in different order in Chrome and Firefox
|
||||||
|
return pc.getStats(selector, (response) => {
|
||||||
|
var report = this.standardizeReport(response);
|
||||||
|
successCb(report);
|
||||||
|
}, failureCb);
|
||||||
|
} else if (adapter.browserDetails.browser === 'chrome') {
|
||||||
|
// In Chrome, the first two arguments are reversed
|
||||||
|
return pc.getStats((response) => {
|
||||||
|
var report = this.standardizeReport(response);
|
||||||
|
successCb(report);
|
||||||
|
}, selector, failureCb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"target": "es5",
|
"target": "es6",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
//"noImplicitAny": true,
|
//"noImplicitAny": true,
|
||||||
"noImplicitThis": true,
|
"noImplicitThis": true,
|
||||||
|
|
Loading…
Reference in New Issue