瀏覽代碼

feat: Moves connectionquality to lib-jitsi-meet.

j8
Boris Grozev 8 年之前
父節點
當前提交
051db50b3f
共有 3 個檔案被更改,包括 11 行新增233 行删除
  1. 11
    30
      conference.js
  2. 0
    196
      modules/connectionquality/connectionquality.js
  3. 0
    7
      service/connectionquality/CQEvents.js

+ 11
- 30
conference.js 查看文件

4
 import ContactList from './modules/UI/side_pannels/contactlist/ContactList';
4
 import ContactList from './modules/UI/side_pannels/contactlist/ContactList';
5
 
5
 
6
 import AuthHandler from './modules/UI/authentication/AuthHandler';
6
 import AuthHandler from './modules/UI/authentication/AuthHandler';
7
-
8
-import ConnectionQuality from './modules/connectionquality/connectionquality';
9
-
10
 import Recorder from './modules/recorder/Recorder';
7
 import Recorder from './modules/recorder/Recorder';
11
 
8
 
12
-import CQEvents from './service/connectionquality/CQEvents';
13
-import UIEvents from './service/UI/UIEvents';
14
-
15
 import mediaDeviceHelper from './modules/devices/mediaDeviceHelper';
9
 import mediaDeviceHelper from './modules/devices/mediaDeviceHelper';
16
 
10
 
17
 import {reportError} from './modules/util/helpers';
11
 import {reportError} from './modules/util/helpers';
18
 
12
 
13
+import UIEvents from './service/UI/UIEvents';
19
 import UIUtil from './modules/UI/util/UIUtil';
14
 import UIUtil from './modules/UI/util/UIUtil';
20
 
15
 
21
 const ConnectionEvents = JitsiMeetJS.events.connection;
16
 const ConnectionEvents = JitsiMeetJS.events.connection;
27
 const TrackEvents = JitsiMeetJS.events.track;
22
 const TrackEvents = JitsiMeetJS.events.track;
28
 const TrackErrors = JitsiMeetJS.errors.track;
23
 const TrackErrors = JitsiMeetJS.errors.track;
29
 
24
 
25
+const ConnectionQualityEvents = JitsiMeetJS.events.connectionQuality;
26
+
30
 let room, connection, localAudio, localVideo;
27
 let room, connection, localAudio, localVideo;
31
 
28
 
32
 /**
29
 /**
769
      * Returns the stats.
766
      * Returns the stats.
770
      */
767
      */
771
     getStats() {
768
     getStats() {
772
-        return ConnectionQuality.getStats();
769
+        return room.connectionQuality.getStats();
773
     },
770
     },
774
     // end used by torture
771
     // end used by torture
775
 
772
 
1253
 
1250
 
1254
         room.on(ConferenceEvents.CONNECTION_INTERRUPTED, () => {
1251
         room.on(ConferenceEvents.CONNECTION_INTERRUPTED, () => {
1255
             connectionIsInterrupted = true;
1252
             connectionIsInterrupted = true;
1256
-            ConnectionQuality.updateLocalConnectionQuality(0);
1257
             APP.UI.showLocalConnectionInterrupted(true);
1253
             APP.UI.showLocalConnectionInterrupted(true);
1258
         });
1254
         });
1259
 
1255
 
1310
             });
1306
             });
1311
         }
1307
         }
1312
 
1308
 
1309
+        // TODO: Move this to the library.
1313
         room.on(ConferenceEvents.CONNECTION_STATS, function (stats) {
1310
         room.on(ConferenceEvents.CONNECTION_STATS, function (stats) {
1314
             // if we say video muted we will use old method of calculating
1311
             // if we say video muted we will use old method of calculating
1315
             // quality and will not depend on localVideo if it is missing
1312
             // quality and will not depend on localVideo if it is missing
1316
-            ConnectionQuality.updateLocalStats(
1313
+            room.connectionQuality.updateLocalStats(
1317
                 stats,
1314
                 stats,
1318
                 connectionIsInterrupted,
1315
                 connectionIsInterrupted,
1319
                 localVideo ? localVideo.videoType : undefined,
1316
                 localVideo ? localVideo.videoType : undefined,
1321
                 localVideo ? localVideo.resolution : null);
1318
                 localVideo ? localVideo.resolution : null);
1322
         });
1319
         });
1323
 
1320
 
1324
-        ConnectionQuality.addListener(CQEvents.LOCALSTATS_UPDATED,
1321
+        room.on(ConnectionQualityEvents.LOCAL_STATS_UPDATED,
1325
             (percent, stats) => {
1322
             (percent, stats) => {
1326
                 APP.UI.updateLocalStats(percent, stats);
1323
                 APP.UI.updateLocalStats(percent, stats);
1324
+
1325
+                // TODO: Move this to the library.
1327
                 // Send only the data that remote participants care about.
1326
                 // Send only the data that remote participants care about.
1328
                 let data = {
1327
                 let data = {
1329
                     bitrate: stats.bitrate,
1328
                     bitrate: stats.bitrate,
1341
                 }
1340
                 }
1342
             });
1341
             });
1343
 
1342
 
1344
-        room.on(ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
1345
-            (participant, payload) => {
1346
-                switch(payload.type) {
1347
-                    case this.commands.defaults.CONNECTION_QUALITY: {
1348
-                        let remoteVideo = participant.getTracks()
1349
-                            .find(tr => tr.isVideoTrack());
1350
-                        ConnectionQuality.updateRemoteStats(
1351
-                            participant.getId(),
1352
-                            payload.values,
1353
-                            remoteVideo ? remoteVideo.videoType : undefined,
1354
-                            remoteVideo ? remoteVideo.isMuted() : undefined);
1355
-                        break;
1356
-                    }
1357
-                    default:
1358
-                        console.warn("Unknown datachannel message", payload);
1359
-                }
1360
-            });
1361
-
1362
-        ConnectionQuality.addListener(CQEvents.REMOTESTATS_UPDATED,
1343
+        room.on(ConnectionQualityEvents.REMOTE_STATS_UPDATED,
1363
             (id, percent, stats) => {
1344
             (id, percent, stats) => {
1364
                 APP.UI.updateRemoteStats(id, percent, stats);
1345
                 APP.UI.updateRemoteStats(id, percent, stats);
1365
-            });
1346
+        });
1366
 
1347
 
1367
         room.addCommandListener(this.commands.defaults.ETHERPAD, ({value}) => {
1348
         room.addCommandListener(this.commands.defaults.ETHERPAD, ({value}) => {
1368
             APP.UI.initEtherpad(value);
1349
             APP.UI.initEtherpad(value);

+ 0
- 196
modules/connectionquality/connectionquality.js 查看文件

1
-/* global config */
2
-import EventEmitter from "events";
3
-
4
-import CQEvents from "../../service/connectionquality/CQEvents";
5
-
6
-const eventEmitter = new EventEmitter();
7
-
8
-/**
9
- * local stats
10
- * @type {{}}
11
- */
12
-var stats = {};
13
-
14
-/**
15
- * remote stats
16
- * @type {{}}
17
- */
18
-var remoteStats = {};
19
-
20
-/**
21
- * Quality percent( 100% - good, 0% - bad.) for the local user.
22
- */
23
-var localConnectionQuality = 100;
24
-
25
-/**
26
- * Quality percent( 100% - good, 0% - bad.) stored per id.
27
- */
28
-var remoteConnectionQuality = {};
29
-
30
-/**
31
- * Calculates the quality percent based on passed new and old value.
32
- * @param newVal the new value
33
- * @param oldVal the old value
34
- */
35
-function calculateQuality(newVal, oldVal) {
36
-    return (newVal <= oldVal) ? newVal : (9*oldVal + newVal) / 10;
37
-}
38
-
39
-// webrtc table describing simulcast resolutions and used bandwidth
40
-// https://chromium.googlesource.com/external/webrtc/+/master/webrtc/media/engine/simulcast.cc#42
41
-const _bandwidthMap = [
42
-    { width: 1920, height: 1080, layers:3, max: 5000, min: 800 },
43
-    { width: 1280, height: 720,  layers:3, max: 2500, min: 600 },
44
-    { width: 960,  height: 540,  layers:3, max: 900,  min: 450 },
45
-    { width: 640,  height: 360,  layers:2, max: 700,  min: 150 },
46
-    { width: 480,  height: 270,  layers:2, max: 450,  min: 150 },
47
-    { width: 320,  height: 180,  layers:1, max: 200,  min: 30 }
48
-];
49
-
50
-/**
51
- * We disable quality calculations based on bandwidth if simulcast is disabled,
52
- * or enable it in case of no simulcast and we force it.
53
- * @type {boolean}
54
- */
55
-const disableQualityBasedOnBandwidth =
56
-    config.forceQualityBasedOnBandwidth ? false : config.disableSimulcast;
57
-
58
-/**
59
- * Calculates the quality percentage based on the input resolution height and
60
- * the upload reported by the client. The value is based on the interval from
61
- * _bandwidthMap.
62
- * @param inputHeight the resolution used to open the camera.
63
- * @param upload the upload rate reported by client.
64
- * @returns {int} the percent of upload based on _bandwidthMap and maximum value
65
- * of 100, as values of the map are approximate and clients can stream above
66
- * those values. Returns undefined if no result is found.
67
- */
68
-function calculateQualityUsingUpload(inputHeight, upload) {
69
-    // found resolution from _bandwidthMap which height is equal or less than
70
-    // the inputHeight
71
-    let foundResolution = _bandwidthMap.find((r) => (r.height <= inputHeight));
72
-
73
-    if (!foundResolution)
74
-        return undefined;
75
-
76
-    if (upload <= foundResolution.min)
77
-        return 0;
78
-
79
-    return Math.min(
80
-        ((upload - foundResolution.min)*100)
81
-            / (foundResolution.max - foundResolution.min),
82
-        100);
83
-}
84
-
85
-export default {
86
-    /**
87
-     * Updates the local statistics
88
-     * @param data new statistics
89
-     * @param dontUpdateLocalConnectionQuality {boolean} if true -
90
-     * localConnectionQuality wont be recalculated.
91
-     * @param videoType the local video type
92
-     * @param isMuted current state of local video, whether it is muted
93
-     * @param resolution the current resolution used by local video
94
-     */
95
-    updateLocalStats:
96
-        function (data, dontUpdateLocalConnectionQuality,
97
-                  videoType, isMuted, resolution) {
98
-            stats = data;
99
-            if(!dontUpdateLocalConnectionQuality) {
100
-                let val = this._getNewQualityValue(
101
-                    stats,
102
-                    localConnectionQuality,
103
-                    videoType,
104
-                    isMuted,
105
-                    resolution);
106
-                if (val !== undefined)
107
-                    localConnectionQuality = val;
108
-            }
109
-            eventEmitter.emit(
110
-                CQEvents.LOCALSTATS_UPDATED, localConnectionQuality, stats);
111
-    },
112
-
113
-    /**
114
-     * Updates only the localConnectionQuality value
115
-     * @param values {int} the new value. should be from 0 - 100.
116
-     */
117
-    updateLocalConnectionQuality: function (value) {
118
-        localConnectionQuality = value;
119
-        eventEmitter.emit(CQEvents.LOCALSTATS_UPDATED, localConnectionQuality,
120
-            stats);
121
-    },
122
-
123
-    /**
124
-     * Updates remote statistics
125
-     * @param id the id associated with the statistics
126
-     * @param data the statistics received
127
-     * @param remoteVideoType the video type of the remote video
128
-     * @param isRemoteVideoMuted whether remote video is muted
129
-     */
130
-    updateRemoteStats:
131
-        function (id, data, remoteVideoType, isRemoteVideoMuted) {
132
-            if (!data ||
133
-                !("packetLoss" in data) ||
134
-                !("total" in data.packetLoss)) {
135
-                eventEmitter.emit(CQEvents.REMOTESTATS_UPDATED, id, null, null);
136
-                return;
137
-            }
138
-
139
-            let inputResolution = data.resolution;
140
-            // Use only the fields we need
141
-            data = {bitrate: data.bitrate, packetLoss: data.packetLoss};
142
-
143
-            remoteStats[id] = data;
144
-
145
-            let val = this._getNewQualityValue(
146
-                data,
147
-                remoteConnectionQuality[id],
148
-                remoteVideoType,
149
-                isRemoteVideoMuted,
150
-                inputResolution);
151
-            if (val !== undefined)
152
-                remoteConnectionQuality[id] = val;
153
-
154
-            eventEmitter.emit(
155
-                CQEvents.REMOTESTATS_UPDATED, id,
156
-                remoteConnectionQuality[id], remoteStats[id]);
157
-    },
158
-
159
-    /**
160
-     * Returns the new quality value based on the input parameters.
161
-     * Used to calculate remote and local values.
162
-     * @param data the data
163
-     * @param lastQualityValue the last value we calculated
164
-     * @param videoType need to check whether we are screen sharing
165
-     * @param isMuted is video muted
166
-     * @param resolution the input resolution used by the camera
167
-     * @returns {*} the newly calculated value or undefined if no result
168
-     * @private
169
-     */
170
-    _getNewQualityValue:
171
-        function (data, lastQualityValue, videoType, isMuted, resolution) {
172
-            if (disableQualityBasedOnBandwidth
173
-                || isMuted
174
-                || videoType === 'desktop'
175
-                || !resolution) {
176
-                return calculateQuality(
177
-                    100 - data.packetLoss.total,
178
-                    lastQualityValue || 100);
179
-            } else {
180
-                return calculateQualityUsingUpload(
181
-                    resolution,
182
-                    data.bitrate.upload);
183
-            }
184
-    },
185
-
186
-    /**
187
-     * Returns the local statistics.
188
-     */
189
-    getStats: function () {
190
-        return stats;
191
-    },
192
-
193
-    addListener: function (type, listener) {
194
-        eventEmitter.on(type, listener);
195
-    }
196
-};

+ 0
- 7
service/connectionquality/CQEvents.js 查看文件

1
-var CQEvents = {
2
-    LOCALSTATS_UPDATED: "cq.localstats_updated",
3
-    REMOTESTATS_UPDATED: "cq.remotestats_updated",
4
-    STOP: "cq.stop"
5
-};
6
-
7
-module.exports = CQEvents;

Loading…
取消
儲存