Implements firefox support for the rtp stats
This commit is contained in:
parent
9b5edde621
commit
501c97b27c
194
rtp_sts.js
194
rtp_sts.js
|
@ -102,6 +102,7 @@ PeerStats.prototype.setSsrcAudioLevel = function (ssrc, audioLevel)
|
|||
*/
|
||||
PeerStats.transport = [];
|
||||
|
||||
|
||||
/**
|
||||
* <tt>StatsCollector</tt> registers for stats updates of given
|
||||
* <tt>peerconnection</tt> in given <tt>interval</tt>. On each update particular
|
||||
|
@ -174,9 +175,15 @@ StatsCollector.prototype.start = function ()
|
|||
self.peerconnection.getStats(
|
||||
function (report)
|
||||
{
|
||||
var results = null;
|
||||
if(!report || !report.result || typeof report.result != 'function')
|
||||
return;
|
||||
var results = report.result();
|
||||
{
|
||||
results = report;
|
||||
}
|
||||
else
|
||||
{
|
||||
results = report.result();
|
||||
}
|
||||
//console.error("Got interval report", results);
|
||||
self.currentAudioLevelsReport = results;
|
||||
self.processAudioLevelReport();
|
||||
|
@ -195,12 +202,28 @@ StatsCollector.prototype.start = function ()
|
|||
self.peerconnection.getStats(
|
||||
function (report)
|
||||
{
|
||||
var results = null;
|
||||
if(!report || !report.result || typeof report.result != 'function')
|
||||
return;
|
||||
var results = report.result();
|
||||
{
|
||||
//firefox
|
||||
results = report;
|
||||
}
|
||||
else
|
||||
{
|
||||
//chrome
|
||||
results = report.result();
|
||||
}
|
||||
//console.error("Got interval report", results);
|
||||
self.currentStatsReport = results;
|
||||
self.processStatsReport();
|
||||
try
|
||||
{
|
||||
self.processStatsReport();
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
console.error("Unsupported key:" + e);
|
||||
}
|
||||
|
||||
self.baselineStatsReport = self.currentStatsReport;
|
||||
},
|
||||
self.errorCallback
|
||||
|
@ -210,6 +233,36 @@ StatsCollector.prototype.start = function ()
|
|||
);
|
||||
};
|
||||
|
||||
var keyMap = {
|
||||
"firefox": {
|
||||
"ssrc": "ssrc",
|
||||
"packetsReceived": "packetsReceived",
|
||||
"packetsLost": "packetsLost",
|
||||
"packetsSent": "packetsSent",
|
||||
"bytesReceived": "bytesReceived",
|
||||
"bytesSent": "bytesSent"
|
||||
},
|
||||
"chrome": {
|
||||
"receiveBandwidth": "googAvailableReceiveBandwidth",
|
||||
"sendBandwidth": "googAvailableSendBandwidth",
|
||||
"remoteAddress": "googRemoteAddress",
|
||||
"transportType": "googTransportType",
|
||||
"localAddress": "googLocalAddress",
|
||||
"activeConnection": "googActiveConnection",
|
||||
"ssrc": "ssrc",
|
||||
"packetsReceived": "packetsReceived",
|
||||
"packetsSent": "packetsSent",
|
||||
"packetsLost": "packetsLost",
|
||||
"bytesReceived": "bytesReceived",
|
||||
"bytesSent": "bytesSent",
|
||||
"googFrameHeightReceived": "googFrameHeightReceived",
|
||||
"googFrameWidthReceived": "googFrameWidthReceived",
|
||||
"googFrameHeightSent": "googFrameHeightSent",
|
||||
"googFrameWidthSent": "googFrameWidthSent",
|
||||
"audioInputLevel": "audioInputLevel",
|
||||
"audioOutputLevel": "audioOutputLevel"
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Stats processing logic.
|
||||
|
@ -221,23 +274,29 @@ StatsCollector.prototype.processStatsReport = function () {
|
|||
|
||||
for (var idx in this.currentStatsReport) {
|
||||
var now = this.currentStatsReport[idx];
|
||||
if (now.stat('googAvailableReceiveBandwidth') ||
|
||||
now.stat('googAvailableSendBandwidth'))
|
||||
{
|
||||
PeerStats.bandwidth = {
|
||||
"download": Math.round(
|
||||
(now.stat('googAvailableReceiveBandwidth')) / 1000),
|
||||
"upload": Math.round(
|
||||
(now.stat('googAvailableSendBandwidth')) / 1000)
|
||||
};
|
||||
try {
|
||||
if (getStatValue(now, 'receiveBandwidth') ||
|
||||
getStatValue(now, 'sendBandwidth')) {
|
||||
PeerStats.bandwidth = {
|
||||
"download": Math.round(
|
||||
(getStatValue(now, 'receiveBandwidth')) / 1000),
|
||||
"upload": Math.round(
|
||||
(getStatValue(now, 'sendBandwidth')) / 1000)
|
||||
};
|
||||
}
|
||||
}
|
||||
catch(e){/*not supported*/}
|
||||
|
||||
if(now.type == 'googCandidatePair')
|
||||
{
|
||||
var ip = now.stat('googRemoteAddress');
|
||||
var type = now.stat("googTransportType");
|
||||
var localIP = now.stat("googLocalAddress");
|
||||
var active = now.stat("googActiveConnection");
|
||||
var ip, type, localIP, active;
|
||||
try {
|
||||
ip = getStatValue(now, 'remoteAddress');
|
||||
type = getStatValue(now, "transportType");
|
||||
localIP = getStatValue(now, "localAddress");
|
||||
active = getStatValue(now, "activeConnection");
|
||||
}
|
||||
catch(e){/*not supported*/}
|
||||
if(!ip || !type || !localIP || active != "true")
|
||||
continue;
|
||||
var addressSaved = false;
|
||||
|
@ -256,17 +315,32 @@ StatsCollector.prototype.processStatsReport = function () {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (now.type != 'ssrc') {
|
||||
if(now.type == "candidatepair")
|
||||
{
|
||||
if(now.state == "succeeded")
|
||||
continue;
|
||||
|
||||
var local = this.currentStatsReport[now.localCandidateId];
|
||||
var remote = this.currentStatsReport[now.remoteCandidateId];
|
||||
PeerStats.transport.push({localip: local.ipAddress + ":" + local.portNumber,
|
||||
ip: remote.ipAddress + ":" + remote.portNumber, type: local.transport});
|
||||
|
||||
}
|
||||
|
||||
if (now.type != 'ssrc' && now.type != "outboundrtp" &&
|
||||
now.type != "inboundrtp") {
|
||||
continue;
|
||||
}
|
||||
|
||||
var before = this.baselineStatsReport[idx];
|
||||
if (!before) {
|
||||
console.warn(now.stat('ssrc') + ' not enough data');
|
||||
console.warn(getStatValue(now, 'ssrc') + ' not enough data');
|
||||
continue;
|
||||
}
|
||||
|
||||
var ssrc = now.stat('ssrc');
|
||||
var ssrc = getStatValue(now, 'ssrc');
|
||||
if(!ssrc)
|
||||
continue;
|
||||
var jid = ssrc2jid[ssrc];
|
||||
if (!jid) {
|
||||
console.warn("No jid for ssrc: " + ssrc);
|
||||
|
@ -282,31 +356,30 @@ StatsCollector.prototype.processStatsReport = function () {
|
|||
|
||||
var isDownloadStream = true;
|
||||
var key = 'packetsReceived';
|
||||
if (!now.stat(key))
|
||||
if (!getStatValue(now, key))
|
||||
{
|
||||
isDownloadStream = false;
|
||||
key = 'packetsSent';
|
||||
if (!now.stat(key))
|
||||
if (!getStatValue(now, key))
|
||||
{
|
||||
console.error("No packetsReceived nor packetSent stat found");
|
||||
this.stop();
|
||||
return;
|
||||
console.warn("No packetsReceived nor packetSent stat found");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
var packetsNow = now.stat(key);
|
||||
var packetsNow = getStatValue(now, key);
|
||||
if(!packetsNow || packetsNow < 0)
|
||||
packetsNow = 0;
|
||||
|
||||
var packetsBefore = before.stat(key);
|
||||
var packetsBefore = getStatValue(before, key);
|
||||
if(!packetsBefore || packetsBefore < 0)
|
||||
packetsBefore = 0;
|
||||
var packetRate = packetsNow - packetsBefore;
|
||||
if(!packetRate || packetRate < 0)
|
||||
packetRate = 0;
|
||||
var currentLoss = now.stat('packetsLost');
|
||||
var currentLoss = getStatValue(now, 'packetsLost');
|
||||
if(!currentLoss || currentLoss < 0)
|
||||
currentLoss = 0;
|
||||
var previousLoss = before.stat('packetsLost');
|
||||
var previousLoss = getStatValue(before, 'packetsLost');
|
||||
if(!previousLoss || previousLoss < 0)
|
||||
previousLoss = 0;
|
||||
var lossRate = currentLoss - previousLoss;
|
||||
|
@ -320,15 +393,15 @@ StatsCollector.prototype.processStatsReport = function () {
|
|||
"isDownloadStream": isDownloadStream});
|
||||
|
||||
var bytesReceived = 0, bytesSent = 0;
|
||||
if(now.stat("bytesReceived"))
|
||||
if(getStatValue(now, "bytesReceived"))
|
||||
{
|
||||
bytesReceived = now.stat("bytesReceived") -
|
||||
before.stat("bytesReceived");
|
||||
bytesReceived = getStatValue(now, "bytesReceived") -
|
||||
getStatValue(before, "bytesReceived");
|
||||
}
|
||||
|
||||
if(now.stat("bytesSent"))
|
||||
if(getStatValue(now, "bytesSent"))
|
||||
{
|
||||
bytesSent = now.stat("bytesSent") - before.stat("bytesSent");
|
||||
bytesSent = getStatValue(now, "bytesSent") - getStatValue(before, "bytesSent");
|
||||
}
|
||||
|
||||
var time = Math.round((now.timestamp - before.timestamp) / 1000);
|
||||
|
@ -354,18 +427,19 @@ StatsCollector.prototype.processStatsReport = function () {
|
|||
"download": bytesReceived,
|
||||
"upload": bytesSent});
|
||||
var resolution = {height: null, width: null};
|
||||
if(now.stat("googFrameHeightReceived") &&
|
||||
now.stat("googFrameWidthReceived"))
|
||||
{
|
||||
resolution.height = now.stat("googFrameHeightReceived");
|
||||
resolution.width = now.stat("googFrameWidthReceived");
|
||||
}
|
||||
else if(now.stat("googFrameHeightSent") &&
|
||||
now.stat("googFrameWidthSent"))
|
||||
{
|
||||
resolution.height = now.stat("googFrameHeightSent");
|
||||
resolution.width = now.stat("googFrameWidthSent");
|
||||
try {
|
||||
if (getStatValue(now, "googFrameHeightReceived") &&
|
||||
getStatValue(now, "googFrameWidthReceived")) {
|
||||
resolution.height = getStatValue(now, "googFrameHeightReceived");
|
||||
resolution.width = getStatValue(now, "googFrameWidthReceived");
|
||||
}
|
||||
else if (getStatValue(now, "googFrameHeightSent") &&
|
||||
getStatValue(now, "googFrameWidthSent")) {
|
||||
resolution.height = getStatValue(now, "googFrameHeightSent");
|
||||
resolution.width = getStatValue(now, "googFrameWidthSent");
|
||||
}
|
||||
}
|
||||
catch(e){/*not supported*/}
|
||||
|
||||
if(resolution.height && resolution.width)
|
||||
{
|
||||
|
@ -413,6 +487,7 @@ StatsCollector.prototype.processStatsReport = function () {
|
|||
}
|
||||
);
|
||||
|
||||
console.log("!!!!!!!!!! " + bitrateDownload + " - " + bitrateUpload);
|
||||
PeerStats.bitrate = {"upload": bitrateUpload, "download": bitrateDownload};
|
||||
|
||||
PeerStats.packetLoss = {
|
||||
|
@ -458,11 +533,11 @@ StatsCollector.prototype.processAudioLevelReport = function ()
|
|||
var before = this.baselineAudioLevelsReport[idx];
|
||||
if (!before)
|
||||
{
|
||||
console.warn(now.stat('ssrc') + ' not enough data');
|
||||
console.warn(getStatValue(now, 'ssrc') + ' not enough data');
|
||||
continue;
|
||||
}
|
||||
|
||||
var ssrc = now.stat('ssrc');
|
||||
var ssrc = getStatValue(now, 'ssrc');
|
||||
var jid = ssrc2jid[ssrc];
|
||||
if (!jid)
|
||||
{
|
||||
|
@ -478,9 +553,19 @@ StatsCollector.prototype.processAudioLevelReport = function ()
|
|||
}
|
||||
|
||||
// Audio level
|
||||
var audioLevel = now.stat('audioInputLevel');
|
||||
if (!audioLevel)
|
||||
audioLevel = now.stat('audioOutputLevel');
|
||||
var audioLevel = null;
|
||||
|
||||
try {
|
||||
audioLevel = getStatValue(now, 'audioInputLevel');
|
||||
if (!audioLevel)
|
||||
audioLevel = getStatValue(now, 'audioOutputLevel');
|
||||
}
|
||||
catch(e) {/*not supported*/
|
||||
console.warn("Audio Levels are not available in the statistics.");
|
||||
clearInterval(this.audioLevelsIntervalId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioLevel)
|
||||
{
|
||||
// TODO: can't find specs about what this value really is,
|
||||
|
@ -495,3 +580,10 @@ StatsCollector.prototype.processAudioLevelReport = function ()
|
|||
|
||||
|
||||
};
|
||||
|
||||
function getStatValue(item, name) {
|
||||
if(!keyMap[RTC.browser][name])
|
||||
throw "The property isn't supported!";
|
||||
var key = keyMap[RTC.browser][name];
|
||||
return RTC.browser == "chrome"? item.stat(key) : item[key];
|
||||
}
|
|
@ -1640,7 +1640,7 @@ var VideoLayout = (function (my) {
|
|||
endpointSimulcastLayers.forEach(function (esl) {
|
||||
|
||||
var resource = esl.endpoint;
|
||||
if (lastNCount < 1 || lastNEndpointsCache.indexOf(resource) === -1) {
|
||||
if (lastNCount !== -1 && (lastNCount < 1 || lastNEndpointsCache.indexOf(resource) === -1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1686,7 +1686,7 @@ var VideoLayout = (function (my) {
|
|||
endpointSimulcastLayers.forEach(function (esl) {
|
||||
|
||||
var resource = esl.endpoint;
|
||||
if (lastNCount < 1 || lastNEndpointsCache.indexOf(resource) === -1) {
|
||||
if (lastNCount !== -1 && (lastNCount < 1 || lastNEndpointsCache.indexOf(resource) === -1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1861,19 +1861,25 @@ var VideoLayout = (function (my) {
|
|||
if(this.jid==null)
|
||||
{
|
||||
resolution = "";
|
||||
for(var i in this.resolution)
|
||||
if(this.resolution == null || !Object.keys(this.resolution)
|
||||
|| Object.keys(this.resolution).length == 0)
|
||||
{
|
||||
resolutionValue = this.resolution[i];
|
||||
if(resolutionValue)
|
||||
resolution = "N/A";
|
||||
}
|
||||
else
|
||||
for(var i in this.resolution)
|
||||
{
|
||||
if(resolutionValue.height &&
|
||||
resolutionValue.width)
|
||||
resolutionValue = this.resolution[i];
|
||||
if(resolutionValue)
|
||||
{
|
||||
resolution += (resolution == ""? "" : ", ")
|
||||
+ resolutionValue.width + "x" + resolutionValue.height;
|
||||
if(resolutionValue.height &&
|
||||
resolutionValue.width)
|
||||
{
|
||||
resolution += (resolution == ""? "" : ", ")
|
||||
+ resolutionValue.width + "x" + resolutionValue.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!resolutionValue ||
|
||||
!resolutionValue.height ||
|
||||
|
|
Loading…
Reference in New Issue