Integrates callstats.io API.

This commit is contained in:
hristoterezov 2015-06-26 15:32:40 +03:00
parent 239f271caf
commit 506312ac95
13 changed files with 873 additions and 629 deletions

View File

@ -35,6 +35,9 @@ var config = {
// startAudioMuted: 10, //every participant after the Nth will start audio muted
// startVideoMuted: 10, //every participant after the Nth will start video muted
// defaultLanguage: "en",
// To enable sending statistics to callstats.io you should provide Applicaiton ID and Secret.
// callStatsID: "",//Application ID for callstats.io API
// callStatsSecret: ""//Secret for callstats.io API
/*noticeMessage: 'Service update is scheduled for 16th March 2015. ' +
'During that time service will not be available. ' +
'Apologise for inconvenience.'*/

View File

@ -9,8 +9,11 @@
<meta itemprop="name" content="Jitsi Meet"/>
<meta itemprop="description" content="Join a WebRTC video conference powered by the Jitsi Videobridge"/>
<meta itemprop="image" content="/images/jitsilogo.png"/>
<script src="https://api.callstats.io/static/callstats.min.js"></script>
<script src="libs/jquery-2.1.1.min.js"></script>
<script src="config.js?v=9"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsSHA/1.5.0/sha.js"></script>
<script src="config.js?v=10"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
<script src="libs/strophe/strophe.min.js?v=1"></script>
<script src="libs/strophe/strophe.disco.min.js?v=1"></script>
<script src="libs/strophe/strophe.caps.jsonly.min.js?v=1"></script>
@ -19,7 +22,7 @@
<script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
<script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
<script src="interface_config.js?v=5"></script>
<script src="libs/app.bundle.js?v=90"></script>
<script src="libs/app.bundle.js?v=91"></script>
<script src="analytics.js?v=1"></script><!-- google analytics plugin -->
<link rel="stylesheet" href="css/font.css?v=7"/>
<link rel="stylesheet" href="css/toastr.css?v=1">

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
var RTCEvents = require("../../service/RTC/RTCEvents");
function LocalStream(stream, type, eventEmitter, videoType, isGUMStream)
@ -54,12 +55,18 @@ LocalStream.prototype.setMute = function(mute)
for (var idx = 0; idx < tracks.length; idx++) {
tracks[idx].enabled = mute;
}
this.eventEmitter.emit(
(this.type == "audio"? RTCEvents.AUDIO_MUTE : RTCEvents.VIDEO_MUTE),
!mute);
}
else
{
if(mute === false) {
APP.xmpp.removeStream(this.stream);
this.stream.stop();
this.eventEmitter.emit(
(this.type == "audio"? RTCEvents.AUDIO_MUTE : RTCEvents.VIDEO_MUTE),
true);
}
else
{
@ -69,11 +76,21 @@ LocalStream.prototype.setMute = function(mute)
function (stream) {
if(self.isAudioStream())
{
APP.RTC.changeLocalAudio(stream, function () {});
APP.RTC.changeLocalAudio(stream,
function () {
self.eventEmitter.emit(
(self.type == "audio"? RTCEvents.AUDIO_MUTE : RTCEvents.VIDEO_MUTE),
true);
});
}
else
{
APP.RTC.changeLocalVideo(stream, false, function () {});
APP.RTC.changeLocalVideo(stream, false,
function () {
self.eventEmitter.emit(
(self.type == "audio"? RTCEvents.AUDIO_MUTE : RTCEvents.VIDEO_MUTE),
true);
});
}
});
}

View File

@ -808,7 +808,7 @@ var VideoLayout = (function (my) {
my.onStatsStop = function () {
for(var video in remoteVideos)
{
video.hideIndicator();
remoteVideos[video].hideIndicator();
}
localVideoThumbnail.hideIndicator();
};

View File

@ -0,0 +1,76 @@
var callStats = null;
function initCallback (err, msg) {
console.log("Initializing Status: err="+err+" msg="+msg);
}
var CallStats = {
init: function (jingleSession) {
if(!config.callStatsID || !config.callStatsSecret || callStats !== null)
return;
callStats = new callstats($,io,jsSHA);
this.session = jingleSession;
this.peerconnection = jingleSession.peerconnection.peerconnection;
this.userID = APP.xmpp.myResource();
var roomJid = APP.UI.getRoomName();
this.confID = roomJid? Strophe.getNodeFromJid(roomJid) : null;
//userID is generated or given by the origin server
callStats.initialize(config.callStatsID,
config.callStatsSecret,
this.userID,
initCallback);
var usage = callStats.fabricUsage.unbundled;
if(config.useBundle)
usage = callStats.fabricUsage.multiplex;
callStats.addNewFabric(this.peerconnection,
Strophe.getResourceFromJid(jingleSession.peerjid),
usage,
this.confID,
this.pcCallback.bind(this));
},
pcCallback: function (err, msg) {
if(!callStats)
return;
console.log("Monitoring status: "+ err + " msg: " + msg);
callStats.sendFabricEvent(this.peerconnection,
callStats.fabricEvent.fabricSetup, this.confID);
},
sendMuteEvent: function (mute, type) {
if(!callStats)
return;
var event = null;
if(type === "video")
{
event = (mute? callStats.fabricEvent.videoPause :
callStats.fabricEvent.videoResume);
}
else
{
event = (mute? callStats.fabricEvent.audioMute :
callStats.fabricEvent.audioUnmute);
}
callStats.sendFabricEvent(this.peerconnection, event, this.confID);
},
sendTerminateEvent: function () {
if(!callStats)
return;
callStats.sendFabricEvent(this.peerconnection,
callStats.fabricEvent.fabricTerminated, this.confID);
},
sendSetupFailedEvent: function () {
if(!callStats)
return;
callStats.sendFabricEvent(this.peerconnection,
callStats.fabricEvent.fabricSetupFailed, this.confID);
}
};
module.exports = CallStats;

View File

@ -6,6 +6,8 @@ var RTPStats = require("./RTPStatsCollector.js");
var EventEmitter = require("events");
var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
var XMPPEvents = require("../../service/xmpp/XMPPEvents");
var CallStats = require("./callstats");
var RTCEvents = require("../../service/RTC/RTCEvents");
var eventEmitter = new EventEmitter();
@ -54,6 +56,7 @@ function onStreamCreated(stream)
}
function onDisposeConference(onUnload) {
CallStats.sendTerminateEvent();
stopRemote();
if(onUnload) {
stopLocal();
@ -119,8 +122,22 @@ var statistics =
APP.RTC.addStreamListener(onStreamCreated,
StreamEventTypes.EVENT_TYPE_LOCAL_CREATED);
APP.xmpp.addListener(XMPPEvents.DISPOSE_CONFERENCE, onDisposeConference);
//FIXME: we may want to change CALL INCOMING event to onnegotiationneeded
APP.xmpp.addListener(XMPPEvents.CALL_INCOMING, function (event) {
startRemoteStats(event.peerconnection);
// CallStats.init(event);
});
APP.xmpp.addListener(XMPPEvents.PEERCONNECTION_READY, function (session) {
CallStats.init(session);
})
APP.RTC.addListener(RTCEvents.AUDIO_MUTE, function (mute) {
CallStats.sendMuteEvent(mute, "audio");
});
APP.xmpp.addListener(XMPPEvents.CONFERENCE_SETUP_FAILED, function () {
CallStats.sendSetupFailedEvent();
})
APP.RTC.addListener(RTCEvents.VIDEO_MUTE, function (mute) {
CallStats.sendMuteEvent(mute, "video");
});
}

View File

@ -3,12 +3,12 @@ var TraceablePeerConnection = require("./TraceablePeerConnection");
var SDPDiffer = require("./SDPDiffer");
var SDPUtil = require("./SDPUtil");
var SDP = require("./SDP");
var RTCBrowserType = require("../../service/RTC/RTCBrowserType");
var async = require("async");
var transform = require("sdp-transform");
var XMPPEvents = require("../../service/xmpp/XMPPEvents");
// Jingle stuff
function JingleSession(me, sid, connection, service) {
function JingleSession(me, sid, connection, service, eventEmitter) {
this.me = me;
this.sid = sid;
this.connection = connection;
@ -47,6 +47,7 @@ function JingleSession(me, sid, connection, service) {
this.wait = true;
this.localStreamsSSRC = null;
this.eventEmitter = eventEmitter;
/**
* The indicator which determines whether the (local) video has been muted
@ -89,7 +90,8 @@ JingleSession.prototype.initiate = function (peerjid, isInitiator) {
this.peerconnection
= new TraceablePeerConnection(
this.connection.jingle.ice_config,
this.connection.jingle.pc_constraints );
this.connection.jingle.pc_constraints,
this);
this.peerconnection.onicecandidate = function (event) {
self.sendIceCandidate(event.candidate);
@ -125,9 +127,15 @@ JingleSession.prototype.initiate = function (peerjid, isInitiator) {
case 'disconnected':
this.stopTime = new Date();
break;
case 'failed':
self.eventEmitter(XMPPEvents.CONFERENCE_SETUP_FAILED);
break;
}
onIceConnectionStateChange(self.sid, self);
};
this.peerconnection.onnegotiationneeded = function (event) {
self.eventEmitter.emit(XMPPEvents.PEERCONNECTION_READY, self);
};
// add any local and relayed stream
APP.RTC.localStreams.forEach(function(stream) {
self.peerconnection.addStream(stream.getOriginalStream());
@ -238,6 +246,7 @@ JingleSession.prototype.accept = function () {
},
function (e) {
console.error('setLocalDescription failed', e);
self.eventEmitter.emit(XMPPEvents.CONFERENCE_SETUP_FAILED);
}
);
};
@ -448,6 +457,7 @@ JingleSession.prototype.createdOffer = function (sdp) {
},
function (e) {
console.error('setLocalDescription failed', e);
self.eventEmitter.emit(XMPPEvents.CONFERENCE_SETUP_FAILED);
}
);
var cands = SDPUtil.find_lines(this.localSDP.raw, 'a=candidate:');
@ -622,6 +632,7 @@ JingleSession.prototype.sendAnswer = function (provisional) {
},
function (e) {
console.error('createAnswer failed', e);
self.eventEmitter.emit(XMPPEvents.CONFERENCE_SETUP_FAILED);
},
this.media_constraints
);
@ -681,6 +692,7 @@ JingleSession.prototype.createdAnswer = function (sdp, provisional) {
},
function (e) {
console.error('setLocalDescription failed', e);
self.eventEmitter.emit(XMPPEvents.CONFERENCE_SETUP_FAILED);
}
);
var cands = SDPUtil.find_lines(this.localSDP.raw, 'a=candidate:');
@ -1232,6 +1244,7 @@ JingleSession.onJingleFatalError = function (session, error)
this.connection.emuc.doLeave();
APP.UI.messageHandler.showError("dialog.sorry",
"dialog.internalError");
this.eventEmitter.emit(XMPPEvents.CONFERENCE_SETUP_FAILED);
}
JingleSession.prototype.setLocalDescription = function () {
@ -1287,6 +1300,7 @@ JingleSession.prototype.setLocalDescription = function () {
function sendKeyframe(pc) {
console.log('sendkeyframe', pc.iceConnectionState);
if (pc.iceConnectionState !== 'connected') return; // safe...
var self = this;
pc.setRemoteDescription(
pc.remoteDescription,
function () {

View File

@ -1,4 +1,6 @@
function TraceablePeerConnection(ice_config, constraints) {
var XMPPEvents = require("../../service/xmpp/XMPPEvents");
function TraceablePeerConnection(ice_config, constraints, session) {
var self = this;
var RTCPeerconnection = navigator.mozGetUserMedia ? mozRTCPeerConnection : webkitRTCPeerConnection;
this.peerconnection = new RTCPeerconnection(ice_config, constraints);

View File

@ -119,7 +119,7 @@ module.exports = function(XMPP, eventEmitter)
}
sess = new JingleSession(
$(iq).attr('to'), $(iq).find('jingle').attr('sid'),
this.connection, XMPP);
this.connection, XMPP, eventEmitter);
// configure session
sess.media_constraints = this.media_constraints;
@ -199,7 +199,7 @@ module.exports = function(XMPP, eventEmitter)
initiate: function (peerjid, myjid) { // initiate a new jinglesession to peerjid
var sess = new JingleSession(myjid || this.connection.jid,
Math.random().toString(36).substr(2, 12), // random string
this.connection, XMPP);
this.connection, XMPP, eventEmitter);
// configure session
sess.media_constraints = this.media_constraints;

View File

@ -315,7 +315,6 @@ var XMPP = {
return Strophe.getResourceFromJid(connection.emuc.myroomjid);
},
disposeConference: function (onUnload) {
eventEmitter.emit(XMPPEvents.DISPOSE_CONFERENCE, onUnload);
var handler = connection.jingle.activecall;
if (handler && handler.peerconnection) {
// FIXME: probably removing streams is not required and close() should
@ -330,6 +329,7 @@ var XMPP = {
}
handler.peerconnection.close();
}
eventEmitter.emit(XMPPEvents.DISPOSE_CONFERENCE, onUnload);
connection.jingle.activecall = null;
if(!onUnload)
{

View File

@ -2,7 +2,9 @@ var RTCEvents = {
LASTN_CHANGED: "rtc.lastn_changed",
DOMINANTSPEAKER_CHANGED: "rtc.dominantspeaker_changed",
LASTN_ENDPOINT_CHANGED: "rtc.lastn_endpoint_changed",
AVAILABLE_DEVICES_CHANGED: "rtc.available_devices_changed"
AVAILABLE_DEVICES_CHANGED: "rtc.available_devices_changed",
AUDIO_MUTE: "rtc.audio_mute",
VIDEO_MUTE: "rtc.video_mute"
};
module.exports = RTCEvents;

View File

@ -1,7 +1,6 @@
var XMPPEvents = {
CONNECTION_FAILED: "xmpp.connection.failed",
CONFERENCE_CREATED: "xmpp.conferenceCreated.jingle",
CALL_TERMINATED: "xmpp.callterminated.jingle",
CALL_INCOMING: "xmpp.callincoming.jingle",
DISPOSE_CONFERENCE: "xmpp.dispose_conference",
GRACEFUL_SHUTDOWN: "xmpp.graceful_shutdown",
@ -30,6 +29,8 @@ var XMPPEvents = {
CHAT_ERROR_RECEIVED: "xmpp.chat_error_received",
ETHERPAD: "xmpp.etherpad",
DEVICE_AVAILABLE: "xmpp.device_available",
START_MUTED: "xmpp.start_muted"
START_MUTED: "xmpp.start_muted",
PEERCONNECTION_READY: "xmpp.peerconnection_ready",
CONFERENCE_SETUP_FAILED: "xmpp.conference_setup_failed"
};
module.exports = XMPPEvents;