diff --git a/app.js b/app.js
index 716b3ae5b..6abba9548 100644
--- a/app.js
+++ b/app.js
@@ -18,6 +18,10 @@ import RoomnameGenerator from './modules/util/RoomnameGenerator';
import CQEvents from './service/connectionquality/CQEvents';
import UIEvents from './service/UI/UIEvents';
+import UI from "./modules/UI/UI";
+import statistics from "./modules/statistics/statistics";
+import settings from "./modules/settings/Settings";
+
import {openConnection} from './modules/connection';
import AuthHandler from './modules/AuthHandler';
@@ -80,6 +84,10 @@ function buildRoomName () {
const APP = {
+ UI,
+ statistics,
+ settings,
+
init () {
let roomName = buildRoomName();
this.conference = {
@@ -94,29 +102,28 @@ const APP = {
},
muteAudio (mute) {
APP.UI.eventEmitter.emit(UIEvents.AUDIO_MUTED, mute);
+ APP.statistics.onAudioMute(mute);
},
toggleAudioMuted () {
this.muteAudio(!this.audioMuted);
},
muteVideo (mute) {
APP.UI.eventEmitter.emit(UIEvents.VIDEO_MUTED, mute);
+ APP.statistics.onVideoMute(mute);
},
toggleVideoMuted () {
this.muteVideo(!this.videoMuted);
}
};
- this.UI = require("./modules/UI/UI");
this.API = require("./modules/API/API");
this.connectionquality =
require("./modules/connectionquality/connectionquality");
- this.statistics = require("./modules/statistics/statistics");
this.desktopsharing =
require("./modules/desktopsharing/desktopsharing");
this.keyboardshortcut =
require("./modules/keyboardshortcut/keyboardshortcut");
this.translation = require("./modules/translation/translation");
- this.settings = require("./modules/settings/Settings");
this.configFetch = require("./modules/config/HttpConfigFetch");
}
};
@@ -126,6 +133,7 @@ function initConference(localTracks, connection) {
openSctp: config.openSctp,
disableAudioLevels: config.disableAudioLevels
});
+ APP.conference._room = room; // FIXME do not use this
const addTrack = (track) => {
room.addTrack(track);
@@ -464,6 +472,8 @@ function initConference(localTracks, connection) {
window.location.pathname = "/";
}, 3000);
}
+ }, function (err) {
+ console.error(err);
});
});
@@ -598,6 +608,7 @@ function createLocalTracks () {
devices: ['audio', 'video']
}).catch(function (err) {
console.error('failed to create local tracks', err);
+ APP.statistics.onGetUserMediaFailed(err);
return [];
});
}
@@ -688,7 +699,7 @@ $(document).ready(function () {
URLProcessor.setConfigParametersFromUrl();
APP.init();
- APP.translation.init();
+ APP.translation.init(settings.getLanguage());
if (APP.API.isEnabled()) {
APP.API.init();
diff --git a/modules/UI/Feedback.js b/modules/UI/Feedback.js
index c9bbea0d6..419d3715d 100644
--- a/modules/UI/Feedback.js
+++ b/modules/UI/Feedback.js
@@ -1,11 +1,10 @@
-/* global $, config, interfaceConfig */
+/* global $, APP, config, interfaceConfig */
/*
* Created by Yana Stamcheva on 2/10/15.
*/
var messageHandler = require("./util/MessageHandler");
var callStats = require("../statistics/CallStats");
-var APP = require("../../app");
/**
* Constructs the html for the overall feedback window.
diff --git a/modules/UI/UI.js b/modules/UI/UI.js
index 49a457439..b0c884102 100644
--- a/modules/UI/UI.js
+++ b/modules/UI/UI.js
@@ -16,16 +16,15 @@ import EtherpadManager from './etherpad/Etherpad';
import VideoLayout from "./videolayout/VideoLayout";
import SettingsMenu from "./side_pannels/settings/SettingsMenu";
+import Settings from "./../settings/Settings";
var EventEmitter = require("events");
-var Settings = require("./../settings/Settings");
UI.messageHandler = require("./util/MessageHandler");
var messageHandler = UI.messageHandler;
var JitsiPopover = require("./util/JitsiPopover");
var CQEvents = require("../../service/connectionquality/CQEvents");
var DesktopSharingEventTypes
= require("../../service/desktopsharing/DesktopSharingEventTypes");
-var StatisticsEvents = require("../../service/statistics/Events");
var Feedback = require("./Feedback");
var eventEmitter = new EventEmitter();
@@ -611,8 +610,8 @@ UI.updateLocalStats = function (percent, stats) {
VideoLayout.updateLocalConnectionStats(percent, stats);
};
-UI.updateRemoteStats = function (jid, percent, stats) {
- VideoLayout.updateConnectionStats(jid, percent, stats);
+UI.updateRemoteStats = function (id, percent, stats) {
+ VideoLayout.updateConnectionStats(id, percent, stats);
};
UI.markVideoInterrupted = function (interrupted) {
diff --git a/modules/UI/videolayout/RemoteVideo.js b/modules/UI/videolayout/RemoteVideo.js
index 4fe7dd463..66a35c132 100644
--- a/modules/UI/videolayout/RemoteVideo.js
+++ b/modules/UI/videolayout/RemoteVideo.js
@@ -296,6 +296,12 @@ RemoteVideo.prototype.showPeerContainer = function (state) {
};
+RemoteVideo.prototype.updateResolution = function (resolution) {
+ if (this.connectionIndicator) {
+ this.connectionIndicator.updateResolution(resolution);
+ }
+};
+
RemoteVideo.prototype.removeConnectionIndicator = function () {
if (this.connectionIndicator)
this.connectionIndicator.remove();
diff --git a/modules/UI/videolayout/VideoLayout.js b/modules/UI/videolayout/VideoLayout.js
index 2a471ee0f..683693fb5 100644
--- a/modules/UI/videolayout/VideoLayout.js
+++ b/modules/UI/videolayout/VideoLayout.js
@@ -733,23 +733,25 @@ var VideoLayout = {
* @param object
*/
updateLocalConnectionStats (percent, object) {
- var resolution = null;
+ let resolutions = {};
if (object.resolution !== null) {
- resolution = object.resolution;
- object.resolution = resolution[APP.xmpp.myJid()];
- delete resolution[APP.xmpp.myJid()];
+ resolutions = object.resolution;
+ object.resolution = resolutions[APP.conference.localId];
}
localVideoThumbnail.updateStatsIndicator(percent, object);
- for (var jid in resolution) {
- if (resolution[jid] === null)
- continue;
- var resourceJid = Strophe.getResourceFromJid(jid);
- if (remoteVideos[resourceJid] &&
- remoteVideos[resourceJid].connectionIndicator) {
- remoteVideos[resourceJid].connectionIndicator.
- updateResolution(resolution[jid]);
+
+ Object.keys(resolutions).forEach(function (id) {
+ if (APP.conference.isLocalId(id)) {
+ return;
}
- }
+
+ let resolution = resolutions[id];
+ let remoteVideo = remoteVideos[id];
+
+ if (resolution && remoteVideo) {
+ remoteVideo.updateResolution(resolution);
+ }
+ });
},
/**
diff --git a/modules/settings/Settings.js b/modules/settings/Settings.js
index f07b4c282..299057dfa 100644
--- a/modules/settings/Settings.js
+++ b/modules/settings/Settings.js
@@ -1,4 +1,4 @@
-var UsernameGenerator = require('../util/UsernameGenerator');
+import {generateUsername} from '../util/UsernameGenerator';
var email = '';
var displayName = '';
@@ -32,7 +32,7 @@ if (supportsLocalStorage()) {
if (!window.localStorage.callStatsUserName) {
window.localStorage.callStatsUserName
- = UsernameGenerator.generateUsername();
+ = generateUsername();
console.log('generated callstats uid',
window.localStorage.callStatsUserName);
@@ -45,10 +45,10 @@ if (supportsLocalStorage()) {
} else {
console.log("local storage is not supported");
userId = generateUniqueId();
- callStatsUserName = UsernameGenerator.generateUsername();
+ callStatsUserName = generateUsername();
}
-var Settings = {
+export default {
/**
* Sets the local user display name and saves it to local storage
@@ -99,10 +99,11 @@ var Settings = {
language: language
};
},
+ getLanguage () {
+ return language;
+ },
setLanguage: function (lang) {
language = lang;
window.localStorage.language = lang;
}
};
-
-module.exports = Settings;
diff --git a/modules/statistics/AnalyticsAdapter.js b/modules/statistics/AnalyticsAdapter.js
index 8492c1123..e66089ad4 100644
--- a/modules/statistics/AnalyticsAdapter.js
+++ b/modules/statistics/AnalyticsAdapter.js
@@ -1,15 +1,19 @@
-function NoopAnalytics() {}
-NoopAnalytics.prototype.sendEvent = function () {};
-
-function AnalyticsAdapter() {
- var AnalyticsImpl = window.Analytics || NoopAnalytics;
- this.analytics = new AnalyticsImpl();
+class NoopAnalytics {
+ sendEvent () {}
}
-AnalyticsAdapter.prototype.sendEvent = function (action, data) {
- try {
- this.analytics.sendEvent.apply(this.analytics, arguments);
- } catch (ignored) {}
-};
+const AnalyticsImpl = window.Analytics || NoopAnalytics;
-module.exports = new AnalyticsAdapter();
\ No newline at end of file
+class AnalyticsAdapter {
+ constructor () {
+ this.analytics = new AnalyticsImpl();
+ }
+
+ sendEvent (...args) {
+ try {
+ this.analytics.sendEvent(...args);
+ } catch (ignored) {}
+ }
+}
+
+export default new AnalyticsAdapter();
diff --git a/modules/statistics/LocalStatsCollector.js b/modules/statistics/LocalStatsCollector.js
deleted file mode 100644
index a3df9ed26..000000000
--- a/modules/statistics/LocalStatsCollector.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/* global config, AudioContext */
-/**
- * Provides statistics for the local stream.
- */
-
-var RTCBrowserType = require('../RTC/RTCBrowserType');
-var StatisticsEvents = require('../../service/statistics/Events');
-
-/**
- * Size of the webaudio analyzer buffer.
- * @type {number}
- */
-var WEBAUDIO_ANALYZER_FFT_SIZE = 2048;
-
-/**
- * Value of the webaudio analyzer smoothing time parameter.
- * @type {number}
- */
-var WEBAUDIO_ANALYZER_SMOOTING_TIME = 0.8;
-
-/**
- * Converts time domain data array to audio level.
- * @param samples the time domain data array.
- * @returns {number} the audio level
- */
-function timeDomainDataToAudioLevel(samples) {
-
- var maxVolume = 0;
-
- var length = samples.length;
-
- for (var i = 0; i < length; i++) {
- if (maxVolume < samples[i])
- maxVolume = samples[i];
- }
-
- return parseFloat(((maxVolume - 127) / 128).toFixed(3));
-}
-
-/**
- * Animates audio level change
- * @param newLevel the new audio level
- * @param lastLevel the last audio level
- * @returns {Number} the audio level to be set
- */
-function animateLevel(newLevel, lastLevel) {
- var value = 0;
- var diff = lastLevel - newLevel;
- if(diff > 0.2) {
- value = lastLevel - 0.2;
- }
- else if(diff < -0.4) {
- value = lastLevel + 0.4;
- }
- else {
- value = newLevel;
- }
-
- return parseFloat(value.toFixed(3));
-}
-
-
-/**
- * LocalStatsCollector calculates statistics for the local stream.
- *
- * @param stream the local stream
- * @param interval stats refresh interval given in ms.
- * @constructor
- */
-function LocalStatsCollector(stream, interval,
- statisticsService, eventEmitter) {
- window.AudioContext = window.AudioContext || window.webkitAudioContext;
- this.stream = stream;
- this.intervalId = null;
- this.intervalMilis = interval;
- this.eventEmitter = eventEmitter;
- this.audioLevel = 0;
- this.statisticsService = statisticsService;
-}
-
-/**
- * Starts the collecting the statistics.
- */
-LocalStatsCollector.prototype.start = function () {
- if (config.disableAudioLevels || !window.AudioContext ||
- RTCBrowserType.isTemasysPluginUsed())
- return;
-
- var context = new AudioContext();
- var analyser = context.createAnalyser();
- analyser.smoothingTimeConstant = WEBAUDIO_ANALYZER_SMOOTING_TIME;
- analyser.fftSize = WEBAUDIO_ANALYZER_FFT_SIZE;
-
-
- var source = context.createMediaStreamSource(this.stream);
- source.connect(analyser);
-
-
- var self = this;
-
- this.intervalId = setInterval(
- function () {
- var array = new Uint8Array(analyser.frequencyBinCount);
- analyser.getByteTimeDomainData(array);
- var audioLevel = timeDomainDataToAudioLevel(array);
- if (audioLevel != self.audioLevel) {
- self.audioLevel = animateLevel(audioLevel, self.audioLevel);
- self.eventEmitter.emit(
- StatisticsEvents.AUDIO_LEVEL,
- self.statisticsService.LOCAL_JID,
- self.audioLevel);
- }
- },
- this.intervalMilis
- );
-};
-
-/**
- * Stops collecting the statistics.
- */
-LocalStatsCollector.prototype.stop = function () {
- if (this.intervalId) {
- clearInterval(this.intervalId);
- this.intervalId = null;
- }
-};
-
-module.exports = LocalStatsCollector;
\ No newline at end of file
diff --git a/modules/statistics/RTPStatsCollector.js b/modules/statistics/RTPStatsCollector.js
index 0dbb6a737..9bbcad6f3 100644
--- a/modules/statistics/RTPStatsCollector.js
+++ b/modules/statistics/RTPStatsCollector.js
@@ -385,7 +385,7 @@ StatsCollector.prototype.addStatsToBeLogged = function (reports) {
StatsCollector.prototype.logStats = function () {
- if(!APP.xmpp.sendLogs(this.statsToBeLogged))
+ if(!APP.conference._room.xmpp.sendLogs(this.statsToBeLogged))
return;
// Reset the stats
this.statsToBeLogged.stats = {};
@@ -501,7 +501,7 @@ StatsCollector.prototype.processStatsReport = function () {
var ssrc = getStatValue(now, 'ssrc');
if(!ssrc)
continue;
- var jid = APP.xmpp.getJidFromSSRC(ssrc);
+ var jid = APP.conference._room.room.getJidBySSRC(ssrc);
if (!jid && (Date.now() - now.timestamp) < 3000) {
console.warn("No jid for ssrc: " + ssrc);
continue;
@@ -647,12 +647,20 @@ StatsCollector.prototype.processStatsReport = function () {
upload:
calculatePacketLoss(lostPackets.upload, totalPackets.upload)
};
+
+ let idResolution = {};
+ if (resolutions) { // use id instead of jid
+ Object.keys(resolutions).forEach(function (jid) {
+ let id = Strophe.getResourceFromJid(jid);
+ resolution[id] = resolutions[id];
+ });
+ }
this.eventEmitter.emit(StatisticsEvents.CONNECTION_STATS,
{
"bitrate": PeerStats.bitrate,
"packetLoss": PeerStats.packetLoss,
"bandwidth": PeerStats.bandwidth,
- "resolution": resolutions,
+ "resolution": idResolution,
"transport": PeerStats.transport
});
PeerStats.transport = [];
@@ -681,7 +689,7 @@ StatsCollector.prototype.processAudioLevelReport = function () {
}
var ssrc = getStatValue(now, 'ssrc');
- var jid = APP.xmpp.getJidFromSSRC(ssrc);
+ var jid = APP.conference._room.room.getJidBySSRC(ssrc);
if (!jid) {
if((Date.now() - now.timestamp) < 3000)
console.warn("No jid for ssrc: " + ssrc);
@@ -713,7 +721,7 @@ StatsCollector.prototype.processAudioLevelReport = function () {
// but it seems to vary between 0 and around 32k.
audioLevel = audioLevel / 32767;
jidStats.setSsrcAudioLevel(ssrc, audioLevel);
- if (jid != APP.xmpp.myJid()) {
+ if (jid != APP.conference._room.room.myroomjid) {
this.eventEmitter.emit(
StatisticsEvents.AUDIO_LEVEL, jid, audioLevel);
}
diff --git a/modules/statistics/statistics.js b/modules/statistics/statistics.js
index 578970f5e..b84fd0d30 100644
--- a/modules/statistics/statistics.js
+++ b/modules/statistics/statistics.js
@@ -2,7 +2,6 @@
/**
* Created by hristo on 8/4/14.
*/
-var LocalStats = require("./LocalStatsCollector.js");
var RTPStats = require("./RTPStatsCollector.js");
var EventEmitter = require("events");
var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
@@ -13,17 +12,8 @@ var StatisticsEvents = require("../../service/statistics/Events");
var eventEmitter = new EventEmitter();
-var localStats = null;
-
var rtpStats = null;
-function stopLocal() {
- if (localStats) {
- localStats.stop();
- localStats = null;
- }
-}
-
function stopRemote() {
if (rtpStats) {
rtpStats.stop();
@@ -41,26 +31,15 @@ function startRemoteStats (peerconnection) {
rtpStats.start();
}
-function onStreamCreated(stream) {
- if(stream.getOriginalStream().getAudioTracks().length === 0) {
- return;
- }
-
- localStats = new LocalStats(stream.getOriginalStream(), 200, statistics,
- eventEmitter);
- localStats.start();
-}
-
function onDisposeConference(onUnload) {
CallStats.sendTerminateEvent();
stopRemote();
- if(onUnload) {
- stopLocal();
+ if (onUnload) {
eventEmitter.removeAllListeners();
}
}
-var statistics = {
+export default {
/**
* Indicates that this audio level is for local jid.
* @type {string}
@@ -74,65 +53,61 @@ var statistics = {
eventEmitter.removeListener(type, listener);
},
stop: function () {
- stopLocal();
stopRemote();
- if(eventEmitter)
- {
+ if (eventEmitter) {
eventEmitter.removeAllListeners();
}
},
- stopRemoteStatistics: function()
- {
- stopRemote();
+ onAudioMute (mute) {
+ CallStats.sendMuteEvent(mute, "audio");
+ },
+ onVideoMute (mute) {
+ CallStats.sendMuteEvent(mute, "video");
+ },
+ onGetUserMediaFailed (e) {
+ CallStats.sendGetUserMediaFailed(e);
},
start: function () {
- return;
- APP.RTC.addStreamListener(onStreamCreated,
- StreamEventTypes.EVENT_TYPE_LOCAL_CREATED);
- APP.xmpp.addListener(XMPPEvents.DISPOSE_CONFERENCE,
- onDisposeConference);
+ const xmpp = APP.conference._room.xmpp;
+ 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) {
+ xmpp.addListener(XMPPEvents.CALL_INCOMING, function (event) {
startRemoteStats(event.peerconnection);
-// CallStats.init(event);
+ // CallStats.init(event);
});
- APP.xmpp.addListener(XMPPEvents.PEERCONNECTION_READY,
+ 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.init(session);
+ }
+ );
+ xmpp.addListener(XMPPEvents.CONFERENCE_SETUP_FAILED, function () {
CallStats.sendSetupFailedEvent();
});
- APP.RTC.addListener(RTCEvents.VIDEO_MUTE, function (mute) {
- CallStats.sendMuteEvent(mute, "video");
- });
- APP.RTC.addListener(RTCEvents.GET_USER_MEDIA_FAILED, function (e) {
- CallStats.sendGetUserMediaFailed(e);
- });
- APP.xmpp.addListener(RTCEvents.CREATE_OFFER_FAILED, function (e, pc) {
+ xmpp.addListener(RTCEvents.CREATE_OFFER_FAILED, function (e, pc) {
CallStats.sendCreateOfferFailed(e, pc);
});
- APP.xmpp.addListener(RTCEvents.CREATE_ANSWER_FAILED, function (e, pc) {
+ xmpp.addListener(RTCEvents.CREATE_ANSWER_FAILED, function (e, pc) {
CallStats.sendCreateAnswerFailed(e, pc);
});
- APP.xmpp.addListener(
+ xmpp.addListener(
RTCEvents.SET_LOCAL_DESCRIPTION_FAILED,
function (e, pc) {
CallStats.sendSetLocalDescFailed(e, pc);
}
);
- APP.xmpp.addListener(
+ xmpp.addListener(
RTCEvents.SET_REMOTE_DESCRIPTION_FAILED,
function (e, pc) {
CallStats.sendSetRemoteDescFailed(e, pc);
}
);
- APP.xmpp.addListener(
+ xmpp.addListener(
RTCEvents.ADD_ICE_CANDIDATE_FAILED,
function (e, pc) {
CallStats.sendAddIceCandidateFailed(e, pc);
@@ -140,8 +115,3 @@ var statistics = {
);
}
};
-
-
-
-
-module.exports = statistics;
\ No newline at end of file
diff --git a/modules/translation/translation.js b/modules/translation/translation.js
index de3d38fa0..99331d5f3 100644
--- a/modules/translation/translation.js
+++ b/modules/translation/translation.js
@@ -1,7 +1,6 @@
/* global $, require, config, interfaceConfig */
var i18n = require("i18next-client");
var languages = require("../../service/translation/languages");
-var Settings = require("../settings/Settings");
var DEFAULT_LANG = languages.EN;
i18n.addPostProcessor("resolveAppName", function(value, key, options) {
@@ -68,7 +67,7 @@ function initCompleted(t) {
$("[data-i18n]").i18n();
}
-function checkForParameter() {
+function getLangFromQuery() {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i";
diff --git a/modules/util/UsernameGenerator.js b/modules/util/UsernameGenerator.js
index 06a09471d..f894f57ff 100644
--- a/modules/util/UsernameGenerator.js
+++ b/modules/util/UsernameGenerator.js
@@ -1,4 +1,4 @@
-var RandomUtil = require('./RandomUtil');
+import RandomUtil from './RandomUtil';
/**
* from faker.js - Copyright (c) 2014-2015 Matthew Bergman & Marak Squires
@@ -417,13 +417,9 @@ var names = [
* Generate random username.
* @returns {string} random username
*/
-function generateUsername () {
+export function generateUsername () {
var name = RandomUtil.randomElement(names);
var suffix = RandomUtil.randomAlphanumStr(3);
return name + '-' + suffix;
}
-
-module.exports = {
- generateUsername: generateUsername
-};