Procházet zdrojové kódy

use statistics module from the library

j8
isymchych před 9 roky
rodič
revize
d19789005e

+ 0
- 6
app.js Zobrazit soubor

@@ -17,7 +17,6 @@ import URLProcessor from "./modules/config/URLProcessor";
17 17
 import RoomnameGenerator from './modules/util/RoomnameGenerator';
18 18
 
19 19
 import UI from "./modules/UI/UI";
20
-import statistics from "./modules/statistics/statistics";
21 20
 import settings from "./modules/settings/Settings";
22 21
 import conference from './conference';
23 22
 import API from './modules/API/API';
@@ -59,13 +58,10 @@ function buildRoomName () {
59 58
 
60 59
 const APP = {
61 60
     UI,
62
-    statistics,
63 61
     settings,
64 62
     conference,
65 63
     API,
66 64
     init () {
67
-        this.connectionquality =
68
-            require("./modules/connectionquality/connectionquality");
69 65
         this.desktopsharing =
70 66
             require("./modules/desktopsharing/desktopsharing");
71 67
         this.keyboardshortcut =
@@ -87,8 +83,6 @@ function init() {
87 83
             });
88 84
 
89 85
             APP.desktopsharing.init(JitsiMeetJS.isDesktopSharingEnabled());
90
-            APP.statistics.start();
91
-            APP.connectionquality.init();
92 86
             APP.keyboardshortcut.init();
93 87
         }).catch(function (err) {
94 88
             console.error(err);

+ 11
- 9
conference.js Zobrazit soubor

@@ -5,6 +5,8 @@ import createRoomLocker from './modules/UI/authentication/RoomLocker';
5 5
 //FIXME:
6 6
 import AuthHandler from './modules/UI/authentication/AuthHandler';
7 7
 
8
+import ConnectionQuality from './modules/connectionquality/connectionquality';
9
+
8 10
 import CQEvents from './service/connectionquality/CQEvents';
9 11
 import UIEvents from './service/UI/UIEvents';
10 12
 import DSEvents from './service/desktopsharing/DesktopSharingEventTypes';
@@ -154,6 +156,7 @@ class ConferenceConnector {
154 156
         case ConferenceErrors.CONFERENCE_DESTROYED:
155 157
             {
156 158
                 let [reason] = params;
159
+                APP.UI.hideStats();
157 160
                 APP.UI.notifyConferenceDestroyed(reason);
158 161
             }
159 162
             break;
@@ -556,6 +559,7 @@ export default {
556 559
         });
557 560
 
558 561
         room.on(ConferenceEvents.KICKED, () => {
562
+            APP.UI.hideStats();
559 563
             APP.UI.notifyKicked();
560 564
             // FIXME close
561 565
         });
@@ -599,14 +603,17 @@ export default {
599 603
             });
600 604
         }
601 605
 
602
-        APP.connectionquality.addListener(
606
+        room.on(ConferenceEvents.CONNECTION_STATS, function (stats) {
607
+            ConnectionQuality.updateLocalStats(stats);
608
+        });
609
+        ConnectionQuality.addListener(
603 610
             CQEvents.LOCALSTATS_UPDATED,
604 611
             (percent, stats) => {
605 612
                 APP.UI.updateLocalStats(percent, stats);
606 613
 
607 614
                 // send local stats to other users
608 615
                 room.sendCommandOnce(Commands.CONNECTION_QUALITY, {
609
-                    children: APP.connectionquality.convertToMUCStats(stats),
616
+                    children: ConnectionQuality.convertToMUCStats(stats),
610 617
                     attributes: {
611 618
                         xmlns: 'http://jitsi.org/jitmeet/stats'
612 619
                     }
@@ -614,17 +621,12 @@ export default {
614 621
             }
615 622
         );
616 623
 
617
-        APP.connectionquality.addListener(CQEvents.STOP, () => {
618
-            APP.UI.hideStats();
619
-            room.removeCommand(Commands.CONNECTION_QUALITY);
620
-        });
621
-
622 624
         // listen to remote stats
623 625
         room.addCommandListener(Commands.CONNECTION_QUALITY,(values, from) => {
624
-            APP.connectionquality.updateRemoteStats(from, values);
626
+            ConnectionQuality.updateRemoteStats(from, values);
625 627
         });
626 628
 
627
-        APP.connectionquality.addListener(CQEvents.REMOTESTATS_UPDATED,
629
+        ConnectionQuality.addListener(CQEvents.REMOTESTATS_UPDATED,
628 630
             (id, percent, stats) => {
629 631
                 APP.UI.updateRemoteStats(id, percent, stats);
630 632
             });

+ 8
- 40
modules/UI/videolayout/ConnectionIndicator.js Zobrazit soubor

@@ -59,7 +59,7 @@ ConnectionIndicator.getStringFromArray = function (array) {
59 59
  * @returns {string} the html content.
60 60
  */
61 61
 ConnectionIndicator.prototype.generateText = function () {
62
-    var downloadBitrate, uploadBitrate, packetLoss, resolution, i;
62
+    var downloadBitrate, uploadBitrate, packetLoss, i;
63 63
 
64 64
     var translate = APP.translation.translateString;
65 65
 
@@ -86,44 +86,12 @@ ConnectionIndicator.prototype.generateText = function () {
86 86
             "%";
87 87
     }
88 88
 
89
-    var resolutionValue = null;
90
-    if(this.resolution && this.id) {
91
-        var keys = Object.keys(this.resolution);
92
-        for(var ssrc in this.resolution) {
93
-            // skip resolutions for ssrc that don't have this info
94
-            // like receive-only ssrc for FF
95
-            if(this.resolution[ssrc]
96
-                && this.resolution[ssrc].height != -1
97
-                && this.resolution[ssrc].width != -1)
98
-            resolutionValue = this.resolution[ssrc];
99
-        }
100
-    }
101
-
102
-    if(this.id === null) {
103
-        resolution = "";
104
-        if(this.resolution === null || !Object.keys(this.resolution) ||
105
-            Object.keys(this.resolution).length === 0) {
106
-            resolution = "N/A";
107
-        } else {
108
-            for (i in this.resolution) {
109
-                resolutionValue = this.resolution[i];
110
-                if (resolutionValue) {
111
-                    if (resolutionValue.height &&
112
-                        resolutionValue.width) {
113
-                        resolution += (resolution === "" ? "" : ", ") +
114
-                        resolutionValue.width + "x" +
115
-                        resolutionValue.height;
116
-                    }
117
-                }
118
-            }
119
-        }
120
-    } else if(!resolutionValue ||
121
-        !resolutionValue.height ||
122
-        !resolutionValue.width) {
123
-        resolution = "N/A";
124
-    } else {
125
-        resolution = resolutionValue.width + "x" + resolutionValue.height;
126
-    }
89
+    // GENERATE RESOLUTIONS STRING
90
+    let resolutions = this.resolution || {};
91
+    let resolutionStr = Object.keys(resolutions).map(function (ssrc) {
92
+        let {width, height} = resolutions[ssrc];
93
+        return `${width}x${height}`;
94
+    }).join(', ') || 'N/A';
127 95
 
128 96
     var result = "<table style='width:100%'>" +
129 97
         "<tr>" +
@@ -139,7 +107,7 @@ ConnectionIndicator.prototype.generateText = function () {
139 107
         "</tr><tr>" +
140 108
         "<td><span class='jitsipopover_blue' data-i18n='connectionindicator.resolution'>" +
141 109
         translate("connectionindicator.resolution") + "</span></td>" +
142
-        "<td>" + resolution + "</td></tr></table>";
110
+        "<td>" + resolutionStr + "</td></tr></table>";
143 111
 
144 112
     if(this.videoContainer.videoSpanId == "localVideoContainer") {
145 113
         result += "<div class=\"jitsipopover_showmore\" " +

+ 3
- 7
modules/UI/videolayout/VideoLayout.js Zobrazit soubor

@@ -728,13 +728,9 @@ var VideoLayout = {
728 728
      * @param object
729 729
      */
730 730
     updateLocalConnectionStats (percent, object) {
731
-        let resolutions = {};
732
-        if (object.resolution !== null) {
733
-            resolutions = object.resolution;
734
-            var id = Strophe.getResourceFromJid(
735
-                APP.conference._room.room.session.me);
736
-            object.resolution = resolutions[id];
737
-        }
731
+        let resolutions = object.resolution;
732
+
733
+        object.resolution = resolutions[APP.conference.localId];
738 734
         localVideoThumbnail.updateStatsIndicator(percent, object);
739 735
 
740 736
         Object.keys(resolutions).forEach(function (id) {

+ 6
- 24
modules/connectionquality/connectionquality.js Zobrazit soubor

@@ -1,9 +1,10 @@
1 1
 /* global APP, require */
2 2
 /* jshint -W101 */
3
-var EventEmitter = require("events");
4
-var eventEmitter = new EventEmitter();
5
-var CQEvents = require("../../service/connectionquality/CQEvents");
6
-var StatisticsEvents = require("../../service/statistics/Events");
3
+import EventEmitter from "events";
4
+
5
+import CQEvents from "../../service/connectionquality/CQEvents";
6
+
7
+const eventEmitter = new EventEmitter();
7 8
 
8 9
 /**
9 10
  * local stats
@@ -50,16 +51,7 @@ function parseMUCStats(stats) {
50 51
     };
51 52
 }
52 53
 
53
-var ConnectionQuality = {
54
-    init: function () {
55
-        APP.statistics.addListener(
56
-            StatisticsEvents.CONNECTION_STATS, this.updateLocalStats
57
-        );
58
-        APP.statistics.addListener(
59
-            StatisticsEvents.STOP, this.stopSendingStats
60
-        );
61
-    },
62
-
54
+export default {
63 55
     /**
64 56
      * Updates the local statistics
65 57
      * @param data new statistics
@@ -87,14 +79,6 @@ var ConnectionQuality = {
87 79
         );
88 80
     },
89 81
 
90
-    /**
91
-     * Stops statistics sending.
92
-     */
93
-    stopSendingStats: function () {
94
-        //notify UI about stopping statistics gathering
95
-        eventEmitter.emit(CQEvents.STOP);
96
-    },
97
-
98 82
     /**
99 83
      * Returns the local statistics.
100 84
      */
@@ -125,5 +109,3 @@ var ConnectionQuality = {
125 109
         ];
126 110
     }
127 111
 };
128
-
129
-module.exports = ConnectionQuality;

+ 1
- 1
modules/statistics/AnalyticsAdapter.js Zobrazit soubor

@@ -1,4 +1,4 @@
1
-/* global config JitsiMeetJS */
1
+/* global config, JitsiMeetJS */
2 2
 
3 3
 // Load the integration of a third-party analytics API such as Google Analytics.
4 4
 // Since we cannot guarantee the quality of the third-party service (e.g. their

+ 0
- 664
modules/statistics/RTPStatsCollector.js Zobrazit soubor

@@ -1,664 +0,0 @@
1
-/* global require, ssrc2jid */
2
-/* jshint -W117 */
3
-/* jshint -W101 */
4
-var RTCBrowserType = require("../RTC/RTCBrowserType");
5
-var StatisticsEvents = require("../../service/statistics/Events");
6
-
7
-/* Whether we support the browser we are running into for logging statistics */
8
-var browserSupported = RTCBrowserType.isChrome() ||
9
-    RTCBrowserType.isOpera() || RTCBrowserType.isFirefox();
10
-/**
11
- * Calculates packet lost percent using the number of lost packets and the
12
- * number of all packet.
13
- * @param lostPackets the number of lost packets
14
- * @param totalPackets the number of all packets.
15
- * @returns {number} packet loss percent
16
- */
17
-function calculatePacketLoss(lostPackets, totalPackets) {
18
-    if(!totalPackets || totalPackets <= 0 || !lostPackets || lostPackets <= 0)
19
-        return 0;
20
-    return Math.round((lostPackets/totalPackets)*100);
21
-}
22
-
23
-function getStatValue(item, name) {
24
-    var browserType = RTCBrowserType.getBrowserType();
25
-    if (!keyMap[browserType][name])
26
-        throw "The property isn't supported!";
27
-    var key = keyMap[browserType][name];
28
-    return (RTCBrowserType.isChrome() || RTCBrowserType.isOpera()) ?
29
-        item.stat(key) : item[key];
30
-}
31
-
32
-/**
33
- * Peer statistics data holder.
34
- * @constructor
35
- */
36
-function PeerStats()
37
-{
38
-    this.ssrc2Loss = {};
39
-    this.ssrc2AudioLevel = {};
40
-    this.ssrc2bitrate = {};
41
-    this.ssrc2resolution = {};
42
-}
43
-
44
-/**
45
- * The bandwidth
46
- * @type {{}}
47
- */
48
-PeerStats.bandwidth = {};
49
-
50
-/**
51
- * The bit rate
52
- * @type {{}}
53
- */
54
-PeerStats.bitrate = {};
55
-
56
-/**
57
- * The packet loss rate
58
- * @type {{}}
59
- */
60
-PeerStats.packetLoss = null;
61
-
62
-/**
63
- * Sets packets loss rate for given <tt>ssrc</tt> that blong to the peer
64
- * represented by this instance.
65
- * @param ssrc audio or video RTP stream SSRC.
66
- * @param lossRate new packet loss rate value to be set.
67
- */
68
-PeerStats.prototype.setSsrcLoss = function (ssrc, lossRate)
69
-{
70
-    this.ssrc2Loss[ssrc] = lossRate;
71
-};
72
-
73
-/**
74
- * Sets resolution for given <tt>ssrc</tt> that belong to the peer
75
- * represented by this instance.
76
- * @param ssrc audio or video RTP stream SSRC.
77
- * @param resolution new resolution value to be set.
78
- */
79
-PeerStats.prototype.setSsrcResolution = function (ssrc, resolution)
80
-{
81
-    if(resolution === null && this.ssrc2resolution[ssrc])
82
-    {
83
-        delete this.ssrc2resolution[ssrc];
84
-    }
85
-    else if(resolution !== null)
86
-        this.ssrc2resolution[ssrc] = resolution;
87
-};
88
-
89
-/**
90
- * Sets the bit rate for given <tt>ssrc</tt> that blong to the peer
91
- * represented by this instance.
92
- * @param ssrc audio or video RTP stream SSRC.
93
- * @param bitrate new bitrate value to be set.
94
- */
95
-PeerStats.prototype.setSsrcBitrate = function (ssrc, bitrate)
96
-{
97
-    if(this.ssrc2bitrate[ssrc])
98
-    {
99
-        this.ssrc2bitrate[ssrc].download += bitrate.download;
100
-        this.ssrc2bitrate[ssrc].upload += bitrate.upload;
101
-    }
102
-    else {
103
-        this.ssrc2bitrate[ssrc] = bitrate;
104
-    }
105
-};
106
-
107
-/**
108
- * Sets new audio level(input or output) for given <tt>ssrc</tt> that identifies
109
- * the stream which belongs to the peer represented by this instance.
110
- * @param ssrc RTP stream SSRC for which current audio level value will be
111
- *        updated.
112
- * @param audioLevel the new audio level value to be set. Value is truncated to
113
- *        fit the range from 0 to 1.
114
- */
115
-PeerStats.prototype.setSsrcAudioLevel = function (ssrc, audioLevel)
116
-{
117
-    // Range limit 0 - 1
118
-    this.ssrc2AudioLevel[ssrc] = formatAudioLevel(audioLevel);
119
-};
120
-
121
-function formatAudioLevel(audioLevel) {
122
-    return Math.min(Math.max(audioLevel, 0), 1);
123
-}
124
-
125
-/**
126
- * Array with the transport information.
127
- * @type {Array}
128
- */
129
-PeerStats.transport = [];
130
-
131
-
132
-/**
133
- * <tt>StatsCollector</tt> registers for stats updates of given
134
- * <tt>peerconnection</tt> in given <tt>interval</tt>. On each update particular
135
- * stats are extracted and put in {@link PeerStats} objects. Once the processing
136
- * is done <tt>audioLevelsUpdateCallback</tt> is called with <tt>this</tt>
137
- * instance as an event source.
138
- *
139
- * @param peerconnection webRTC peer connection object.
140
- * @param interval stats refresh interval given in ms.
141
- * @param {function(StatsCollector)} audioLevelsUpdateCallback the callback
142
- * called on stats update.
143
- * @constructor
144
- */
145
-function StatsCollector(peerconnection, audioLevelsInterval, statsInterval, eventEmitter)
146
-{
147
-    this.peerconnection = peerconnection;
148
-    this.baselineAudioLevelsReport = null;
149
-    this.currentStatsReport = null;
150
-    this.baselineStatsReport = null;
151
-    this.audioLevelsIntervalId = null;
152
-    this.eventEmitter = eventEmitter;
153
-
154
-    /**
155
-     * Gather PeerConnection stats once every this many milliseconds.
156
-     */
157
-    this.GATHER_INTERVAL = 15000;
158
-
159
-    /**
160
-     * Log stats via the focus once every this many milliseconds.
161
-     */
162
-    this.LOG_INTERVAL = 60000;
163
-
164
-    /**
165
-     * Gather stats and store them in this.statsToBeLogged.
166
-     */
167
-    this.gatherStatsIntervalId = null;
168
-
169
-    /**
170
-     * Send the stats already saved in this.statsToBeLogged to be logged via
171
-     * the focus.
172
-     */
173
-    this.logStatsIntervalId = null;
174
-
175
-    /**
176
-     * Stores the statistics which will be send to the focus to be logged.
177
-     */
178
-    this.statsToBeLogged =
179
-    {
180
-        timestamps: [],
181
-        stats: {}
182
-    };
183
-
184
-    // Updates stats interval
185
-    this.audioLevelsIntervalMilis = audioLevelsInterval;
186
-
187
-    this.statsIntervalId = null;
188
-    this.statsIntervalMilis = statsInterval;
189
-    // Map of jids to PeerStats
190
-    this.jid2stats = {};
191
-}
192
-
193
-module.exports = StatsCollector;
194
-
195
-/**
196
- * Stops stats updates.
197
- */
198
-StatsCollector.prototype.stop = function () {
199
-    if (this.audioLevelsIntervalId) {
200
-        clearInterval(this.audioLevelsIntervalId);
201
-        this.audioLevelsIntervalId = null;
202
-    }
203
-
204
-    if (this.statsIntervalId)
205
-    {
206
-        clearInterval(this.statsIntervalId);
207
-        this.statsIntervalId = null;
208
-    }
209
-
210
-    if(this.logStatsIntervalId)
211
-    {
212
-        clearInterval(this.logStatsIntervalId);
213
-        this.logStatsIntervalId = null;
214
-    }
215
-
216
-    if(this.gatherStatsIntervalId)
217
-    {
218
-        clearInterval(this.gatherStatsIntervalId);
219
-        this.gatherStatsIntervalId = null;
220
-    }
221
-};
222
-
223
-/**
224
- * Callback passed to <tt>getStats</tt> method.
225
- * @param error an error that occurred on <tt>getStats</tt> call.
226
- */
227
-StatsCollector.prototype.errorCallback = function (error)
228
-{
229
-    console.error("Get stats error", error);
230
-    this.stop();
231
-};
232
-
233
-/**
234
- * Starts stats updates.
235
- */
236
-StatsCollector.prototype.start = function ()
237
-{
238
-    var self = this;
239
-    if (!config.disableAudioLevels) {
240
-        this.audioLevelsIntervalId = setInterval(
241
-            function () {
242
-                // Interval updates
243
-                self.peerconnection.getStats(
244
-                    function (report) {
245
-                        var results = null;
246
-                        if (!report || !report.result ||
247
-                            typeof report.result != 'function') {
248
-                            results = report;
249
-                        }
250
-                        else {
251
-                            results = report.result();
252
-                        }
253
-                        //console.error("Got interval report", results);
254
-                        self.baselineAudioLevelsReport = results;
255
-                    },
256
-                    self.errorCallback
257
-                );
258
-            },
259
-            self.audioLevelsIntervalMilis
260
-        );
261
-    }
262
-
263
-    if (!config.disableStats && browserSupported) {
264
-        this.statsIntervalId = setInterval(
265
-            function () {
266
-                // Interval updates
267
-                self.peerconnection.getStats(
268
-                    function (report) {
269
-                        var results = null;
270
-                        if (!report || !report.result ||
271
-                            typeof report.result != 'function') {
272
-                            //firefox
273
-                            results = report;
274
-                        }
275
-                        else {
276
-                            //chrome
277
-                            results = report.result();
278
-                        }
279
-                        //console.error("Got interval report", results);
280
-                        self.currentStatsReport = results;
281
-                        try {
282
-                            self.processStatsReport();
283
-                        }
284
-                        catch (e) {
285
-                            console.error("Unsupported key:" + e, e);
286
-                        }
287
-
288
-                        self.baselineStatsReport = self.currentStatsReport;
289
-                    },
290
-                    self.errorCallback
291
-                );
292
-            },
293
-            self.statsIntervalMilis
294
-        );
295
-    }
296
-
297
-    // Logging statistics does not support firefox
298
-    if (config.logStats && (browserSupported && !RTCBrowserType.isFirefox())) {
299
-        this.gatherStatsIntervalId = setInterval(
300
-            function () {
301
-                self.peerconnection.getStats(
302
-                    function (report) {
303
-                        self.addStatsToBeLogged(report.result());
304
-                    },
305
-                    function () {
306
-                    }
307
-                );
308
-            },
309
-            this.GATHER_INTERVAL
310
-        );
311
-
312
-        this.logStatsIntervalId = setInterval(
313
-            function() { self.logStats(); },
314
-            this.LOG_INTERVAL);
315
-    }
316
-};
317
-
318
-/**
319
- * Checks whether a certain record should be included in the logged statistics.
320
- */
321
-function acceptStat(reportId, reportType, statName) {
322
-    if (reportType == "googCandidatePair" && statName == "googChannelId")
323
-        return false;
324
-
325
-    if (reportType == "ssrc") {
326
-        if (statName == "googTrackId" ||
327
-            statName == "transportId" ||
328
-            statName == "ssrc")
329
-            return false;
330
-    }
331
-
332
-    return true;
333
-}
334
-
335
-/**
336
- * Checks whether a certain record should be included in the logged statistics.
337
- */
338
-function acceptReport(id, type) {
339
-    if (id.substring(0, 15) == "googCertificate" ||
340
-        id.substring(0, 9) == "googTrack" ||
341
-        id.substring(0, 20) == "googLibjingleSession")
342
-        return false;
343
-
344
-    if (type == "googComponent")
345
-        return false;
346
-
347
-    return true;
348
-}
349
-
350
-/**
351
- * Converts the stats to the format used for logging, and saves the data in
352
- * this.statsToBeLogged.
353
- * @param reports Reports as given by webkitRTCPerConnection.getStats.
354
- */
355
-StatsCollector.prototype.addStatsToBeLogged = function (reports) {
356
-    var self = this;
357
-    var num_records = this.statsToBeLogged.timestamps.length;
358
-    this.statsToBeLogged.timestamps.push(new Date().getTime());
359
-    reports.map(function (report) {
360
-        if (!acceptReport(report.id, report.type))
361
-            return;
362
-        var stat = self.statsToBeLogged.stats[report.id];
363
-        if (!stat) {
364
-            stat = self.statsToBeLogged.stats[report.id] = {};
365
-        }
366
-        stat.type = report.type;
367
-        report.names().map(function (name) {
368
-            if (!acceptStat(report.id, report.type, name))
369
-                return;
370
-            var values = stat[name];
371
-            if (!values) {
372
-                values = stat[name] = [];
373
-            }
374
-            while (values.length < num_records) {
375
-                values.push(null);
376
-            }
377
-            values.push(report.stat(name));
378
-        });
379
-    });
380
-};
381
-
382
-StatsCollector.prototype.logStats = function () {
383
-
384
-    if(!APP.conference._room.xmpp.sendLogs(this.statsToBeLogged))
385
-        return;
386
-    // Reset the stats
387
-    this.statsToBeLogged.stats = {};
388
-    this.statsToBeLogged.timestamps = [];
389
-};
390
-var keyMap = {};
391
-keyMap[RTCBrowserType.RTC_BROWSER_FIREFOX] = {
392
-    "ssrc": "ssrc",
393
-    "packetsReceived": "packetsReceived",
394
-    "packetsLost": "packetsLost",
395
-    "packetsSent": "packetsSent",
396
-    "bytesReceived": "bytesReceived",
397
-    "bytesSent": "bytesSent"
398
-};
399
-keyMap[RTCBrowserType.RTC_BROWSER_CHROME] = {
400
-    "receiveBandwidth": "googAvailableReceiveBandwidth",
401
-    "sendBandwidth": "googAvailableSendBandwidth",
402
-    "remoteAddress": "googRemoteAddress",
403
-    "transportType": "googTransportType",
404
-    "localAddress": "googLocalAddress",
405
-    "activeConnection": "googActiveConnection",
406
-    "ssrc": "ssrc",
407
-    "packetsReceived": "packetsReceived",
408
-    "packetsSent": "packetsSent",
409
-    "packetsLost": "packetsLost",
410
-    "bytesReceived": "bytesReceived",
411
-    "bytesSent": "bytesSent",
412
-    "googFrameHeightReceived": "googFrameHeightReceived",
413
-    "googFrameWidthReceived": "googFrameWidthReceived",
414
-    "googFrameHeightSent": "googFrameHeightSent",
415
-    "googFrameWidthSent": "googFrameWidthSent",
416
-    "audioInputLevel": "audioInputLevel",
417
-    "audioOutputLevel": "audioOutputLevel"
418
-};
419
-keyMap[RTCBrowserType.RTC_BROWSER_OPERA] =
420
-    keyMap[RTCBrowserType.RTC_BROWSER_CHROME];
421
-
422
-
423
-/**
424
- * Stats processing logic.
425
- */
426
-StatsCollector.prototype.processStatsReport = function () {
427
-    if (!this.baselineStatsReport) {
428
-        return;
429
-    }
430
-
431
-    for (var idx in this.currentStatsReport) {
432
-        var now = this.currentStatsReport[idx];
433
-        try {
434
-            if (getStatValue(now, 'receiveBandwidth') ||
435
-                getStatValue(now, 'sendBandwidth')) {
436
-                PeerStats.bandwidth = {
437
-                    "download": Math.round(
438
-                            (getStatValue(now, 'receiveBandwidth')) / 1000),
439
-                    "upload": Math.round(
440
-                            (getStatValue(now, 'sendBandwidth')) / 1000)
441
-                };
442
-            }
443
-        }
444
-        catch(e){/*not supported*/}
445
-
446
-        if(now.type == 'googCandidatePair')
447
-        {
448
-            var ip, type, localIP, active;
449
-            try {
450
-                ip = getStatValue(now, 'remoteAddress');
451
-                type = getStatValue(now, "transportType");
452
-                localIP = getStatValue(now, "localAddress");
453
-                active = getStatValue(now, "activeConnection");
454
-            }
455
-            catch(e){/*not supported*/}
456
-            if(!ip || !type || !localIP || active != "true")
457
-                continue;
458
-            var addressSaved = false;
459
-            for(var i = 0; i < PeerStats.transport.length; i++)
460
-            {
461
-                if(PeerStats.transport[i].ip == ip &&
462
-                    PeerStats.transport[i].type == type &&
463
-                    PeerStats.transport[i].localip == localIP)
464
-                {
465
-                    addressSaved = true;
466
-                }
467
-            }
468
-            if(addressSaved)
469
-                continue;
470
-            PeerStats.transport.push({localip: localIP, ip: ip, type: type});
471
-            continue;
472
-        }
473
-
474
-        if(now.type == "candidatepair")
475
-        {
476
-            if(now.state == "succeeded")
477
-                continue;
478
-
479
-            var local = this.currentStatsReport[now.localCandidateId];
480
-            var remote = this.currentStatsReport[now.remoteCandidateId];
481
-            PeerStats.transport.push({localip: local.ipAddress + ":" + local.portNumber,
482
-                ip: remote.ipAddress + ":" + remote.portNumber, type: local.transport});
483
-
484
-        }
485
-
486
-        if (now.type != 'ssrc' && now.type != "outboundrtp" &&
487
-            now.type != "inboundrtp") {
488
-            continue;
489
-        }
490
-
491
-        var before = this.baselineStatsReport[idx];
492
-        if (!before) {
493
-            console.warn(getStatValue(now, 'ssrc') + ' not enough data');
494
-            continue;
495
-        }
496
-
497
-        var ssrc = getStatValue(now, 'ssrc');
498
-        if(!ssrc)
499
-            continue;
500
-        var jid = APP.conference._room.room.getJidBySSRC(ssrc);
501
-        if (!jid && (Date.now() - now.timestamp) < 3000) {
502
-            console.warn("No jid for ssrc: " + ssrc);
503
-            continue;
504
-        }
505
-
506
-        var jidStats = this.jid2stats[jid];
507
-        if (!jidStats) {
508
-            jidStats = new PeerStats();
509
-            this.jid2stats[jid] = jidStats;
510
-        }
511
-
512
-
513
-        var isDownloadStream = true;
514
-        var key = 'packetsReceived';
515
-        var packetsNow = getStatValue(now, key);
516
-        if (typeof packetsNow === 'undefined' || packetsNow === null) {
517
-            isDownloadStream = false;
518
-            key = 'packetsSent';
519
-            packetsNow = getStatValue(now, key);
520
-            if (typeof packetsNow === 'undefined' || packetsNow === null) {
521
-                console.warn("No packetsReceived nor packetsSent stat found");
522
-                continue;
523
-            }
524
-        }
525
-        if (!packetsNow || packetsNow < 0)
526
-            packetsNow = 0;
527
-
528
-        var packetsBefore = getStatValue(before, key);
529
-        if (!packetsBefore || packetsBefore < 0)
530
-            packetsBefore = 0;
531
-        var packetRate = packetsNow - packetsBefore;
532
-        if (!packetRate || packetRate < 0)
533
-            packetRate = 0;
534
-        var currentLoss = getStatValue(now, 'packetsLost');
535
-        if (!currentLoss || currentLoss < 0)
536
-            currentLoss = 0;
537
-        var previousLoss = getStatValue(before, 'packetsLost');
538
-        if (!previousLoss || previousLoss < 0)
539
-            previousLoss = 0;
540
-        var lossRate = currentLoss - previousLoss;
541
-        if (!lossRate || lossRate < 0)
542
-            lossRate = 0;
543
-        var packetsTotal = (packetRate + lossRate);
544
-
545
-        jidStats.setSsrcLoss(ssrc,
546
-            {"packetsTotal": packetsTotal,
547
-                "packetsLost": lossRate,
548
-                "isDownloadStream": isDownloadStream});
549
-
550
-
551
-        var bytesReceived = 0, bytesSent = 0;
552
-        if(getStatValue(now, "bytesReceived")) {
553
-            bytesReceived = getStatValue(now, "bytesReceived") -
554
-                getStatValue(before, "bytesReceived");
555
-        }
556
-
557
-        if(getStatValue(now, "bytesSent")) {
558
-            bytesSent = getStatValue(now, "bytesSent") -
559
-                getStatValue(before, "bytesSent");
560
-        }
561
-
562
-        var time = Math.round((now.timestamp - before.timestamp) / 1000);
563
-        if(bytesReceived <= 0 || time <= 0) {
564
-            bytesReceived = 0;
565
-        } else {
566
-            bytesReceived = Math.round(((bytesReceived * 8) / time) / 1000);
567
-        }
568
-
569
-        if(bytesSent <= 0 || time <= 0) {
570
-            bytesSent = 0;
571
-        } else {
572
-            bytesSent = Math.round(((bytesSent * 8) / time) / 1000);
573
-        }
574
-
575
-        jidStats.setSsrcBitrate(ssrc, {
576
-            "download": bytesReceived,
577
-            "upload": bytesSent});
578
-
579
-        var resolution = {height: null, width: null};
580
-        try {
581
-            if (getStatValue(now, "googFrameHeightReceived") &&
582
-                getStatValue(now, "googFrameWidthReceived")) {
583
-                resolution.height = getStatValue(now, "googFrameHeightReceived");
584
-                resolution.width = getStatValue(now, "googFrameWidthReceived");
585
-            }
586
-            else if (getStatValue(now, "googFrameHeightSent") &&
587
-                getStatValue(now, "googFrameWidthSent")) {
588
-                resolution.height = getStatValue(now, "googFrameHeightSent");
589
-                resolution.width = getStatValue(now, "googFrameWidthSent");
590
-            }
591
-        }
592
-        catch(e){/*not supported*/}
593
-
594
-        if(resolution.height && resolution.width) {
595
-            jidStats.setSsrcResolution(ssrc, resolution);
596
-        } else {
597
-            jidStats.setSsrcResolution(ssrc, null);
598
-        }
599
-    }
600
-
601
-    var self = this;
602
-    // Jid stats
603
-    var totalPackets = {download: 0, upload: 0};
604
-    var lostPackets = {download: 0, upload: 0};
605
-    var bitrateDownload = 0;
606
-    var bitrateUpload = 0;
607
-    var resolutions = {};
608
-    Object.keys(this.jid2stats).forEach(
609
-        function (jid) {
610
-            Object.keys(self.jid2stats[jid].ssrc2Loss).forEach(
611
-                function (ssrc) {
612
-                    var type = "upload";
613
-                    if(self.jid2stats[jid].ssrc2Loss[ssrc].isDownloadStream)
614
-                        type = "download";
615
-                    totalPackets[type] +=
616
-                        self.jid2stats[jid].ssrc2Loss[ssrc].packetsTotal;
617
-                    lostPackets[type] +=
618
-                        self.jid2stats[jid].ssrc2Loss[ssrc].packetsLost;
619
-                }
620
-            );
621
-            Object.keys(self.jid2stats[jid].ssrc2bitrate).forEach(
622
-                function (ssrc) {
623
-                    bitrateDownload +=
624
-                        self.jid2stats[jid].ssrc2bitrate[ssrc].download;
625
-                    bitrateUpload +=
626
-                        self.jid2stats[jid].ssrc2bitrate[ssrc].upload;
627
-
628
-                    delete self.jid2stats[jid].ssrc2bitrate[ssrc];
629
-                }
630
-            );
631
-            resolutions[jid] = self.jid2stats[jid].ssrc2resolution;
632
-        }
633
-    );
634
-
635
-    PeerStats.bitrate = {"upload": bitrateUpload, "download": bitrateDownload};
636
-
637
-    PeerStats.packetLoss = {
638
-        total:
639
-            calculatePacketLoss(lostPackets.download + lostPackets.upload,
640
-                    totalPackets.download + totalPackets.upload),
641
-        download:
642
-            calculatePacketLoss(lostPackets.download, totalPackets.download),
643
-        upload:
644
-            calculatePacketLoss(lostPackets.upload, totalPackets.upload)
645
-    };
646
-
647
-    let idResolution = {};
648
-    if (resolutions) { // use id instead of jid
649
-        Object.keys(resolutions).forEach(function (jid) {
650
-            let id = Strophe.getResourceFromJid(jid);
651
-            idResolution[id] = resolutions[jid];
652
-        });
653
-    }
654
-    this.eventEmitter.emit(StatisticsEvents.CONNECTION_STATS,
655
-        {
656
-            "bitrate": PeerStats.bitrate,
657
-            "packetLoss": PeerStats.packetLoss,
658
-            "bandwidth": PeerStats.bandwidth,
659
-            "resolution": idResolution,
660
-            "transport": PeerStats.transport
661
-        });
662
-    PeerStats.transport = [];
663
-
664
-};

+ 0
- 71
modules/statistics/statistics.js Zobrazit soubor

@@ -1,71 +0,0 @@
1
-/* global require, APP */
2
-/**
3
- * Created by hristo on 8/4/14.
4
- */
5
-var RTPStats = require("./RTPStatsCollector.js");
6
-var EventEmitter = require("events");
7
-var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
8
-var XMPPEvents = require("../../service/xmpp/XMPPEvents");
9
-var RTCEvents = require("../../service/RTC/RTCEvents");
10
-var StatisticsEvents = require("../../service/statistics/Events");
11
-
12
-var eventEmitter = new EventEmitter();
13
-
14
-var rtpStats = null;
15
-
16
-function stopRemote() {
17
-    if (rtpStats) {
18
-        rtpStats.stop();
19
-        eventEmitter.emit(StatisticsEvents.STOP);
20
-        rtpStats = null;
21
-    }
22
-}
23
-
24
-function startRemoteStats (peerconnection) {
25
-    if (rtpStats) {
26
-        rtpStats.stop();
27
-    }
28
-
29
-    rtpStats = new RTPStats(peerconnection, 200, 2000, eventEmitter);
30
-    rtpStats.start();
31
-}
32
-
33
-function onDisposeConference(onUnload) {
34
-    stopRemote();
35
-    if (onUnload) {
36
-        eventEmitter.removeAllListeners();
37
-    }
38
-}
39
-
40
-export default {
41
-    /**
42
-     * Indicates that this audio level is for local jid.
43
-     * @type {string}
44
-     */
45
-    LOCAL_JID: 'local',
46
-
47
-    addListener: function(type, listener) {
48
-        eventEmitter.on(type, listener);
49
-    },
50
-    removeListener: function (type, listener) {
51
-        eventEmitter.removeListener(type, listener);
52
-    },
53
-    stop: function () {
54
-        stopRemote();
55
-        if (eventEmitter) {
56
-            eventEmitter.removeAllListeners();
57
-        }
58
-    },
59
-    start: function () {
60
-        const xmpp = APP.conference._room.xmpp;
61
-        xmpp.addListener(
62
-            XMPPEvents.DISPOSE_CONFERENCE,
63
-            onDisposeConference
64
-        );
65
-        //FIXME: we may want to change CALL INCOMING event to
66
-        // onnegotiationneeded
67
-        xmpp.addListener(XMPPEvents.CALL_INCOMING, function (event) {
68
-            startRemoteStats(event.peerconnection);
69
-        });
70
-    }
71
-};

+ 0
- 18
service/RTC/RTCEvents.js Zobrazit soubor

@@ -1,18 +0,0 @@
1
-var RTCEvents = {
2
-    RTC_READY: "rtc.ready",
3
-    DATA_CHANNEL_OPEN: "rtc.data_channel_open",
4
-    CREATE_OFFER_FAILED: "rtc.create_offer_failed",
5
-    CREATE_ANSWER_FAILED: "rtc.create_answer_failed",
6
-    SET_LOCAL_DESCRIPTION_FAILED: "rtc.set_local_description_failed",
7
-    SET_REMOTE_DESCRIPTION_FAILED: "rtc.set_remote_description_failed",
8
-    ADD_ICE_CANDIDATE_FAILED: "rtc.add_ice_candidate_failed",
9
-    GET_USER_MEDIA_FAILED: "rtc.get_user_media_failed",
10
-    LASTN_CHANGED: "rtc.lastn_changed",
11
-    DOMINANTSPEAKER_CHANGED: "rtc.dominantspeaker_changed",
12
-    LASTN_ENDPOINT_CHANGED: "rtc.lastn_endpoint_changed",
13
-    AVAILABLE_DEVICES_CHANGED: "rtc.available_devices_changed",
14
-    AUDIO_MUTE: "rtc.audio_mute",
15
-    VIDEO_MUTE: "rtc.video_mute"
16
-};
17
-
18
-module.exports = RTCEvents;

+ 0
- 13
service/RTC/StreamEventTypes.js Zobrazit soubor

@@ -1,13 +0,0 @@
1
-var StreamEventTypes = {
2
-    EVENT_TYPE_LOCAL_CREATED: "stream.local_created",
3
-
4
-    EVENT_TYPE_LOCAL_CHANGED: "stream.local_changed",
5
-
6
-    EVENT_TYPE_LOCAL_ENDED: "stream.local_ended",
7
-
8
-    EVENT_TYPE_REMOTE_CREATED: "stream.remote_created",
9
-
10
-    EVENT_TYPE_REMOTE_ENDED: "stream.remote_ended"
11
-};
12
-
13
-module.exports = StreamEventTypes;

+ 0
- 12
service/authentication/AuthenticationEvents.js Zobrazit soubor

@@ -1,12 +0,0 @@
1
-var AuthenticationEvents = {
2
-    /**
3
-     * Event callback arguments:
4
-     * function(authenticationEnabled, userIdentity)
5
-     * authenticationEnabled - indicates whether authentication has been enabled
6
-     *                         in this session
7
-     * userIdentity - if user has been logged in then it contains user name. If
8
-     *                contains 'null' or 'undefined' then user is not logged in.
9
-     */
10
-    IDENTITY_UPDATED: "authentication.identity_updated"
11
-};
12
-module.exports = AuthenticationEvents;

+ 0
- 14
service/statistics/Events.js Zobrazit soubor

@@ -1,14 +0,0 @@
1
-module.exports = {
2
-    /**
3
-     * An event carrying connection statistics.
4
-     */
5
-    CONNECTION_STATS: "statistics.connectionstats",
6
-    /**
7
-     * FIXME: needs documentation.
8
-     */
9
-    AUDIO_LEVEL: "statistics.audioLevel",
10
-    /**
11
-     * FIXME: needs documentation.
12
-     */
13
-    STOP: "statistics.stop"
14
-};

+ 0
- 92
service/xmpp/XMPPEvents.js Zobrazit soubor

@@ -1,92 +0,0 @@
1
-var XMPPEvents = {
2
-    // Designates an event indicating that the connection to the XMPP server
3
-    // failed.
4
-    CONNECTION_FAILED: "xmpp.connection.failed",
5
-    // Designates an event indicating that the media (ICE) connection was
6
-    // interrupted. This should go to the RTC module.
7
-    CONNECTION_INTERRUPTED: "xmpp.connection.interrupted",
8
-    // Designates an event indicating that the media (ICE) connection was
9
-    // restored. This should go to the RTC module.
10
-    CONNECTION_RESTORED: "xmpp.connection.restored",
11
-    // Designates an event indicating that an offer (e.g. Jingle
12
-    // session-initiate) was received.
13
-    CALL_INCOMING: "xmpp.callincoming.jingle",
14
-    // Designates an event indicating that we were kicked from the XMPP MUC.
15
-    KICKED: "xmpp.kicked",
16
-    // Designates an event indicating that the userID for a specific JID has
17
-    // changed.
18
-    // Note: currently this event fires every time we receive presence from
19
-    // someone (regardless of whether or not the "userID" changed).
20
-    USER_ID_CHANGED: "xmpp.user_id_changed",
21
-    // Designates an event indicating that we have joined the XMPP MUC.
22
-    MUC_JOINED: "xmpp.muc_joined",
23
-    // Designates an event indicating that a participant joined the XMPP MUC.
24
-    MUC_MEMBER_JOINED: "xmpp.muc_member_joined",
25
-    // Designates an event indicating that a participant left the XMPP MUC.
26
-    MUC_MEMBER_LEFT: "xmpp.muc_member_left",
27
-    // Designates an event indicating that the MUC role of a participant has
28
-    // changed.
29
-    MUC_ROLE_CHANGED: "xmpp.muc_role_changed",
30
-    // Designates an event indicating that the XMPP MUC was destroyed.
31
-    MUC_DESTROYED: "xmpp.muc_destroyed",
32
-    // Designates an event indicating that the display name of a participant
33
-    // has changed.
34
-    DISPLAY_NAME_CHANGED: "xmpp.display_name_changed",
35
-    // Designates an event indicating that we received statistics from a
36
-    // participant in the MUC.
37
-    REMOTE_STATS: "xmpp.remote_stats",
38
-    // Designates an event indicating that our role in the XMPP MUC has changed.
39
-    LOCAL_ROLE_CHANGED: "xmpp.localrole_changed",
40
-    // Designates an event indicating that the subject of the XMPP MUC has
41
-    // changed.
42
-    SUBJECT_CHANGED: "xmpp.subject_changed",
43
-    // Designates an event indicating that an XMPP message in the MUC was
44
-    // received.
45
-    MESSAGE_RECEIVED: "xmpp.message_received",
46
-    // Designates an event indicating that we sent an XMPP message to the MUC.
47
-    SENDING_CHAT_MESSAGE: "xmpp.sending_chat_message",
48
-    // Designates an event indicating that the video type (e.g. 'camera' or
49
-    // 'screen') for a participant has changed.
50
-    // Note: currently this event fires every time we receive presence from
51
-    // someone (regardless of whether or not the "video type" changed).
52
-    PARTICIPANT_VIDEO_TYPE_CHANGED: "xmpp.video_type",
53
-    // Designates an event indicating that a participant in the XMPP MUC has
54
-    // advertised that they have audio muted (or unmuted).
55
-    PARTICIPANT_AUDIO_MUTED: "xmpp.audio_muted",
56
-    // Designates an event indicating that a participant in the XMPP MUC has
57
-    // advertised that they have video muted (or unmuted).
58
-    PARTICIPANT_VIDEO_MUTED: "xmpp.video_muted",
59
-    // Designates an event indicating that the focus has asked us to mute our
60
-    // audio.
61
-    AUDIO_MUTED_BY_FOCUS: "xmpp.audio_muted_by_focus",
62
-    // Designates an event indicating that a moderator in the room changed the
63
-    // "start muted" settings for the conference.
64
-    START_MUTED_SETTING_CHANGED: "xmpp.start_muted_setting_changed",
65
-    // Designates an event indicating that we should join the conference with
66
-    // audio and/or video muted.
67
-    START_MUTED_FROM_FOCUS: "xmpp.start_muted_from_focus",
68
-    // Designates an event indicating that a remote participant's available
69
-    // devices (whether he supports a audio and/or video) changed.
70
-    // Note: currently this event fires every time we receive presence from
71
-    // someone (regardless of whether or not the devices changed).
72
-    DEVICE_AVAILABLE: "xmpp.device_available",
73
-
74
-
75
-    PEERCONNECTION_READY: "xmpp.peerconnection_ready",
76
-    CONFERENCE_SETUP_FAILED: "xmpp.conference_setup_failed",
77
-    PASSWORD_REQUIRED: "xmpp.password_required",
78
-    AUTHENTICATION_REQUIRED: "xmpp.authentication_required",
79
-    CHAT_ERROR_RECEIVED: "xmpp.chat_error_received",
80
-    ETHERPAD: "xmpp.etherpad",
81
-    BRIDGE_DOWN: "xmpp.bridge_down",
82
-    PRESENCE_STATUS: "xmpp.presence_status",
83
-    RESERVATION_ERROR: "xmpp.room_reservation_error",
84
-    DISPOSE_CONFERENCE: "xmpp.dispose_conference",
85
-    GRACEFUL_SHUTDOWN: "xmpp.graceful_shutdown",
86
-    JINGLE_FATAL_ERROR: 'xmpp.jingle_fatal_error',
87
-    PROMPT_FOR_LOGIN: 'xmpp.prompt_for_login',
88
-    FOCUS_DISCONNECTED: 'xmpp.focus_disconnected',
89
-    // xmpp is connected and obtained user media
90
-    READY_TO_JOIN: 'xmpp.ready_to_join'
91
-};
92
-module.exports = XMPPEvents;

Načítá se…
Zrušit
Uložit