Browse Source

Merge 2d2387b947 into b03ccff479

pull/134/merge
Joachim Bauch 12 years ago
parent
commit
1e25c399e7
  1. 67
      static/js/libs/webrtc.getstats.js
  2. 4
      static/js/main.js
  3. 18
      static/js/mediastream/peercall.js
  4. 137
      static/js/mediastream/peerconnection.js

67
static/js/libs/webrtc.getstats.js

@ -0,0 +1,67 @@ @@ -0,0 +1,67 @@
/*
* Spreed WebRTC.
* Copyright (C) 2013-2014 struktur AG
*
* This file is part of Spreed WebRTC.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
var getRTCStats = null;
define(['webrtc.adapter'], function() {
switch (webrtcDetectedBrowser) {
case "firefox":
getRTCStats = function(peerconnection, callback) {
peerconnection.getStats(
null,
function (res) {
var items = [];
res.forEach(function(result) {
items.push(result);
});
callback(items);
},
callback
);
};
break;
case "chrome":
getRTCStats = function(peerconnection, callback) {
peerconnection.getStats(function(res) {
var items = [];
res.result().forEach(function(result) {
var item = {};
result.names().forEach(function(name) {
item[name] = result.stat(name);
});
item.id = result.id;
item.type = result.type;
item.timestamp = result.timestamp;
items.push(item);
});
callback(items);
});
};
break;
default:
// browser doesn't support WebRTC
break;
}
});

4
static/js/main.js

@ -27,6 +27,7 @@ require.config({ @@ -27,6 +27,7 @@ require.config({
"underscore": 'libs/lodash.min', // alternative to underscore
"modernizr": 'libs/modernizr',
'webrtc.adapter': 'libs/webrtc.adapter',
'webrtc.getstats': 'libs/webrtc.getstats',
'angular': 'libs/angular/angular.min',
'ui-bootstrap': 'libs/angular/ui-bootstrap-tpls.min',
'ua-parser': 'libs/ua-parser',
@ -133,6 +134,9 @@ require.config({ @@ -133,6 +134,9 @@ require.config({
deps: ['jquery'],
exports: '$'
},
'webrtc.getstats': {
deps: ['webrtc.adapter']
}
}
});

18
static/js/mediastream/peercall.js

@ -180,6 +180,24 @@ define(['jquery', 'underscore', 'mediastream/utils', 'mediastream/peerconnection @@ -180,6 +180,24 @@ define(['jquery', 'underscore', 'mediastream/utils', 'mediastream/peerconnection
};
PeerCall.prototype.onPeerStatisticsChanged = function(statistics) {
this.e.triggerHandler("statisticsChanged", [statistics, this]);
};
PeerCall.prototype.onCertificatesReceived = function(certificates) {
this.e.triggerHandler("certificatesReceived", [certificates, this]);
};
PeerCall.prototype.onCiphersNegotiated = function(ciphers) {
this.e.triggerHandler("ciphersNegotiated", [ciphers, this]);
};
PeerCall.prototype.onRemoteStreamAdded = function(stream) {
this.streams[stream] = true;

137
static/js/mediastream/peerconnection.js

@ -18,11 +18,14 @@ @@ -18,11 +18,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) {
define(['jquery', 'underscore', 'webrtc.adapter', 'webrtc.getstats'], function($, _) {
var count = 0;
var dataChannelDefaultLabel = "default";
// update connection statistics once per second
var STATS_INTERVAL = 1000;
var PeerConnection = function(webrtc, currentcall) {
this.webrtc = webrtc;
@ -31,6 +34,12 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) { @@ -31,6 +34,12 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) {
this.pc = null;
this.datachannel = null;
this.datachannelReady = false;
this.statsActive = false;
this.localCertificate = null;
this.remoteCertificate = null;
this.dtlsCipher = null;
this.srtpCipher = null;
this.notifiedCertificates = false;
if (currentcall) {
this.createPeerConnection(currentcall);
@ -198,10 +207,129 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) { @@ -198,10 +207,129 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) {
};
PeerConnection.prototype.updateStatistics = function(callback) {
getRTCStats(this.pc, _.bind(function(stats) {
if (!this.localCertificate || !this.remoteCertificate || !this.dtlsCipher || !this.srtpCipher) {
var certificates = {};
var dtlsCiphers = {};
var srtpCiphers = {};
var i;
var item;
if (!this.localCertificate || !this.remoteCertificate) {
// build lookup tables
for (i=0; i<stats.length; i++) {
item = stats[i];
switch (item.type) {
case "googCertificate":
certificates[item.id] = {
"fingerprint": item.googFingerprint,
"fingerprintAlgorithm": item.googFingerprintAlgorithm,
"certificateDerBase64": item.googDerBase64
};
break;
default:
break;
}
}
}
for (i=0; i<stats.length; i++) {
var certId;
item = stats[i];
switch (item.type) {
case "googComponent":
certId = item.googLocalCertificateId;
if (!this.localCertificate && certId && certificates.hasOwnProperty(certId)) {
this.localCertificate = certificates[certId];
}
certId = item.googRemoteCertificateId;
if (!this.remoteCertificate && certId && certificates.hasOwnProperty(certId)) {
this.remoteCertificate = certificates[certId];
}
if (item.spreedDtlsCipher) {
dtlsCiphers[item.spreedDtlsCipher] = true;
}
if (item.spreedSrtpCipher) {
srtpCiphers[item.spreedSrtpCipher] = true;
}
break;
default:
break;
}
}
if (!this.dtlsCipher && !_.isEmpty(dtlsCiphers)) {
dtlsCiphers = _.keys(dtlsCiphers);
if (dtlsCiphers.length > 1) {
console.warn("Using multiple DTLS ciphers", dtlsCiphers);
}
this.dtlsCipher = _.reduce(dtlsCiphers, function(a, b) { return a + ", " + b; });
}
if (!this.srtpCipher && !_.isEmpty(srtpCiphers)) {
srtpCiphers = _.keys(srtpCiphers);
if (srtpCiphers.length > 1) {
console.warn("Using multiple SRTP ciphers", srtpCiphers);
}
this.srtpCipher = _.reduce(srtpCiphers, function(a, b) { return a + ", " + b; });
}
if (this.currentcall) {
if (!this.notifiedCertificates && this.localCertificate && this.remoteCertificate) {
this.notifiedCertificates = true;
this.currentcall.onCertificatesReceived({'local': this.localCertificate, 'remote': this.remoteCertificate});
}
if (this.dtlsCipher && this.srtpCipher) {
this.currentcall.onCiphersNegotiated({'dtls': this.dtlsCipher, 'srtp': this.srtpCipher});
}
}
}
if (this.currentcall) {
this.currentcall.onPeerStatisticsChanged(stats);
}
if (callback) {
callback(stats);
}
}, this));
};
PeerConnection.prototype.startStatistics = function() {
if (this.statsActive) {
return;
}
var updateFunc = _.bind(function() {
if (!this.statsActive || !this.pc) {
return;
}
this.updateStatistics(function() {
_.delay(updateFunc, STATS_INTERVAL);
});
}, this);
this.statsActive = true;
updateFunc();
};
PeerConnection.prototype.stopStatistics = function() {
this.statsActive = false;
};
PeerConnection.prototype.onIceConnectionStateChange = function(event) {
var iceConnectionState = event.target.iceConnectionState;
console.info("ICE connection state change", iceConnectionState, event, this.currentcall);
switch (iceConnectionState) {
case "connected":
case "completed":
this.startStatistics();
break;
case "closed":
this.stopStatistics();
break;
}
this.currentcall.onIceConnectionStateChange(iceConnectionState);
};
@ -237,6 +365,7 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) { @@ -237,6 +365,7 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) {
PeerConnection.prototype.close = function() {
this.stopStatistics();
if (this.datachannel) {
this.datachannel.close()
}
@ -311,6 +440,12 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) { @@ -311,6 +440,12 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) {
};
PeerConnection.prototype.getStats = function() {
return this.pc.getStats.apply(this.pc, arguments);
};
return PeerConnection;
});

Loading…
Cancel
Save