Browse Source

Fixes audio level performance issue on avatar.

j8
hristoterezov 10 years ago
parent
commit
f2a7a43ba7

+ 1
- 1
index.html View File

19
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
19
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
20
     <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
20
     <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
21
     <script src="interface_config.js?v=5"></script>
21
     <script src="interface_config.js?v=5"></script>
22
-    <script src="libs/app.bundle.js?v=8"></script>
22
+    <script src="libs/app.bundle.js?v=9"></script>
23
 
23
 
24
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
24
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
25
     <link rel="stylesheet" href="css/font.css?v=6"/>
25
     <link rel="stylesheet" href="css/font.css?v=6"/>

+ 60
- 38
libs/app.bundle.js View File

1315
             VideoLayout.onSimulcastLayersChanging(endpointSimulcastLayers);
1315
             VideoLayout.onSimulcastLayersChanging(endpointSimulcastLayers);
1316
         });
1316
         });
1317
     VideoLayout.init(eventEmitter);
1317
     VideoLayout.init(eventEmitter);
1318
-
1318
+    AudioLevels.init();
1319
     APP.statistics.addAudioLevelListener(function(jid, audioLevel)
1319
     APP.statistics.addAudioLevelListener(function(jid, audioLevel)
1320
     {
1320
     {
1321
         var resourceJid;
1321
         var resourceJid;
1933
 },{"../../service/RTC/RTCEvents":80,"../../service/RTC/StreamEventTypes":81,"../../service/connectionquality/CQEvents":83,"../../service/desktopsharing/DesktopSharingEventTypes":84,"../../service/xmpp/XMPPEvents":86,"./audio_levels/AudioLevels.js":9,"./authentication/Authentication":11,"./avatar/Avatar":12,"./etherpad/Etherpad.js":13,"./prezi/Prezi.js":14,"./side_pannels/SidePanelToggler":16,"./side_pannels/chat/Chat.js":17,"./side_pannels/contactlist/ContactList":21,"./side_pannels/settings/Settings":22,"./side_pannels/settings/SettingsMenu":23,"./toolbars/BottomToolbar":24,"./toolbars/Toolbar":25,"./toolbars/ToolbarToggler":26,"./util/MessageHandler":28,"./util/NicknameHandler":29,"./util/UIUtil":30,"./videolayout/VideoLayout.js":32,"./welcome_page/RoomnameGenerator":33,"./welcome_page/WelcomePage":34,"events":87}],9:[function(require,module,exports){
1933
 },{"../../service/RTC/RTCEvents":80,"../../service/RTC/StreamEventTypes":81,"../../service/connectionquality/CQEvents":83,"../../service/desktopsharing/DesktopSharingEventTypes":84,"../../service/xmpp/XMPPEvents":86,"./audio_levels/AudioLevels.js":9,"./authentication/Authentication":11,"./avatar/Avatar":12,"./etherpad/Etherpad.js":13,"./prezi/Prezi.js":14,"./side_pannels/SidePanelToggler":16,"./side_pannels/chat/Chat.js":17,"./side_pannels/contactlist/ContactList":21,"./side_pannels/settings/Settings":22,"./side_pannels/settings/SettingsMenu":23,"./toolbars/BottomToolbar":24,"./toolbars/Toolbar":25,"./toolbars/ToolbarToggler":26,"./util/MessageHandler":28,"./util/NicknameHandler":29,"./util/UIUtil":30,"./videolayout/VideoLayout.js":32,"./welcome_page/RoomnameGenerator":33,"./welcome_page/WelcomePage":34,"events":87}],9:[function(require,module,exports){
1934
 var CanvasUtil = require("./CanvasUtils");
1934
 var CanvasUtil = require("./CanvasUtils");
1935
 
1935
 
1936
+var ASDrawContext = $('#activeSpeakerAudioLevel')[0].getContext('2d');
1937
+
1938
+function initActiveSpeakerAudioLevels() {
1939
+    var ASRadius = interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE / 2;
1940
+    var ASCenter = (interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE + ASRadius) / 2;
1941
+
1942
+// Draw a circle.
1943
+    ASDrawContext.arc(ASCenter, ASCenter, ASRadius, 0, 2 * Math.PI);
1944
+
1945
+// Add a shadow around the circle
1946
+    ASDrawContext.shadowColor = interfaceConfig.SHADOW_COLOR;
1947
+    ASDrawContext.shadowOffsetX = 0;
1948
+    ASDrawContext.shadowOffsetY = 0;
1949
+}
1950
+
1936
 /**
1951
 /**
1937
  * The audio Levels plugin.
1952
  * The audio Levels plugin.
1938
  */
1953
  */
1941
 
1956
 
1942
     my.LOCAL_LEVEL = 'local';
1957
     my.LOCAL_LEVEL = 'local';
1943
 
1958
 
1959
+    my.init = function () {
1960
+        initActiveSpeakerAudioLevels();
1961
+    }
1962
+
1944
     /**
1963
     /**
1945
      * Updates the audio level canvas for the given peerJid. If the canvas
1964
      * Updates the audio level canvas for the given peerJid. If the canvas
1946
      * didn't exist we create it.
1965
      * didn't exist we create it.
2027
         }
2046
         }
2028
 
2047
 
2029
         if(resourceJid  === largeVideoResourceJid) {
2048
         if(resourceJid  === largeVideoResourceJid) {
2030
-            AudioLevels.updateActiveSpeakerAudioLevel(audioLevel);
2049
+            window.requestAnimationFrame(function () {
2050
+                AudioLevels.updateActiveSpeakerAudioLevel(audioLevel);
2051
+            });
2031
         }
2052
         }
2032
     };
2053
     };
2033
 
2054
 
2034
     my.updateActiveSpeakerAudioLevel = function(audioLevel) {
2055
     my.updateActiveSpeakerAudioLevel = function(audioLevel) {
2035
-        var drawContext = $('#activeSpeakerAudioLevel')[0].getContext('2d');
2036
-        var r = interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE / 2;
2037
-        var center = (interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE + r) / 2;
2056
+        if($("#activeSpeaker").css("visibility") == "hidden")
2057
+            return;
2038
 
2058
 
2039
-        // Save the previous state of the context.
2040
-        drawContext.save();
2041
 
2059
 
2042
-        drawContext.clearRect(0, 0, 300, 300);
2060
+        ASDrawContext.clearRect(0, 0, 300, 300);
2061
+        if(audioLevel == 0)
2062
+            return;
2043
 
2063
 
2044
-        // Draw a circle.
2045
-        drawContext.arc(center, center, r, 0, 2 * Math.PI);
2064
+        ASDrawContext.shadowBlur = getShadowLevel(audioLevel);
2046
 
2065
 
2047
-        // Add a shadow around the circle
2048
-        drawContext.shadowColor = interfaceConfig.SHADOW_COLOR;
2049
-        drawContext.shadowBlur = getShadowLevel(audioLevel);
2050
-        drawContext.shadowOffsetX = 0;
2051
-        drawContext.shadowOffsetY = 0;
2052
 
2066
 
2053
         // Fill the shape.
2067
         // Fill the shape.
2054
-        drawContext.fill();
2055
-
2056
-        drawContext.save();
2057
-
2058
-        drawContext.restore();
2059
-
2060
-
2061
-        drawContext.arc(center, center, r, 0, 2 * Math.PI);
2062
-
2063
-        drawContext.clip();
2064
-        drawContext.clearRect(0, 0, 277, 200);
2065
-
2066
-        // Restore the previous context state.
2067
-        drawContext.restore();
2068
+        ASDrawContext.fill();
2068
     };
2069
     };
2069
 
2070
 
2070
     /**
2071
     /**
10604
 PeerStats.prototype.setSsrcAudioLevel = function (ssrc, audioLevel)
10605
 PeerStats.prototype.setSsrcAudioLevel = function (ssrc, audioLevel)
10605
 {
10606
 {
10606
     // Range limit 0 - 1
10607
     // Range limit 0 - 1
10607
-    this.ssrc2AudioLevel[ssrc] = Math.min(Math.max(audioLevel, 0), 1);
10608
+    this.ssrc2AudioLevel[ssrc] = formatAudioLevel(audioLevel);
10608
 };
10609
 };
10609
 
10610
 
10611
+function formatAudioLevel(audioLevel) {
10612
+    return Math.min(Math.max(audioLevel, 0), 1);
10613
+}
10614
+
10610
 /**
10615
 /**
10611
  * Array with the transport information.
10616
  * Array with the transport information.
10612
  * @type {Array}
10617
  * @type {Array}
10681
 /**
10686
 /**
10682
  * Stops stats updates.
10687
  * Stops stats updates.
10683
  */
10688
  */
10684
-StatsCollector.prototype.stop = function ()
10685
-{
10686
-    if (this.audioLevelsIntervalId)
10687
-    {
10689
+StatsCollector.prototype.stop = function () {
10690
+    if (this.audioLevelsIntervalId) {
10688
         clearInterval(this.audioLevelsIntervalId);
10691
         clearInterval(this.audioLevelsIntervalId);
10689
         this.audioLevelsIntervalId = null;
10692
         this.audioLevelsIntervalId = null;
10693
+    }
10694
+
10695
+    if (this.statsIntervalId)
10696
+    {
10690
         clearInterval(this.statsIntervalId);
10697
         clearInterval(this.statsIntervalId);
10691
         this.statsIntervalId = null;
10698
         this.statsIntervalId = null;
10699
+    }
10700
+
10701
+    if(this.logStatsIntervalId)
10702
+    {
10692
         clearInterval(this.logStatsIntervalId);
10703
         clearInterval(this.logStatsIntervalId);
10693
         this.logStatsIntervalId = null;
10704
         this.logStatsIntervalId = null;
10705
+    }
10706
+
10707
+    if(this.gatherStatsIntervalId)
10708
+    {
10694
         clearInterval(this.gatherStatsIntervalId);
10709
         clearInterval(this.gatherStatsIntervalId);
10695
         this.gatherStatsIntervalId = null;
10710
         this.gatherStatsIntervalId = null;
10696
     }
10711
     }
10713
 {
10728
 {
10714
     var self = this;
10729
     var self = this;
10715
     if(!config.disableAudioLevels) {
10730
     if(!config.disableAudioLevels) {
10731
+        console.debug("set audio levels interval");
10716
         this.audioLevelsIntervalId = setInterval(
10732
         this.audioLevelsIntervalId = setInterval(
10717
             function () {
10733
             function () {
10718
                 // Interval updates
10734
                 // Interval updates
10740
     }
10756
     }
10741
 
10757
 
10742
     if(!config.disableStats) {
10758
     if(!config.disableStats) {
10759
+        console.debug("set stats interval");
10743
         this.statsIntervalId = setInterval(
10760
         this.statsIntervalId = setInterval(
10744
             function () {
10761
             function () {
10745
                 // Interval updates
10762
                 // Interval updates
11170
         {
11187
         {
11171
             // TODO: can't find specs about what this value really is,
11188
             // TODO: can't find specs about what this value really is,
11172
             // but it seems to vary between 0 and around 32k.
11189
             // but it seems to vary between 0 and around 32k.
11173
-            audioLevel = audioLevel / 32767;
11174
-            jidStats.setSsrcAudioLevel(ssrc, audioLevel);
11175
-            if(jid != APP.xmpp.myJid())
11190
+            audioLevel = formatAudioLevel(audioLevel / 32767);
11191
+            var oldLevel = jidStats.ssrc2AudioLevel[ssrc];
11192
+            if(jid != APP.xmpp.myJid() && (!oldLevel || oldLevel != audioLevel))
11193
+            {
11194
+
11195
+                jidStats.ssrc2AudioLevel[ssrc] = audioLevel;
11196
+
11176
                 this.eventEmitter.emit("statistics.audioLevel", jid, audioLevel);
11197
                 this.eventEmitter.emit("statistics.audioLevel", jid, audioLevel);
11198
+            }
11177
         }
11199
         }
11178
 
11200
 
11179
     }
11201
     }
11231
     if(stream.getOriginalStream().getAudioTracks().length === 0)
11253
     if(stream.getOriginalStream().getAudioTracks().length === 0)
11232
         return;
11254
         return;
11233
 
11255
 
11234
-    localStats = new LocalStats(stream.getOriginalStream(), 100, statistics,
11256
+    localStats = new LocalStats(stream.getOriginalStream(), 200, statistics,
11235
         eventEmitter);
11257
         eventEmitter);
11236
     localStats.start();
11258
     localStats.start();
11237
 }
11259
 }

+ 1
- 1
modules/UI/UI.js View File

103
             VideoLayout.onSimulcastLayersChanging(endpointSimulcastLayers);
103
             VideoLayout.onSimulcastLayersChanging(endpointSimulcastLayers);
104
         });
104
         });
105
     VideoLayout.init(eventEmitter);
105
     VideoLayout.init(eventEmitter);
106
-
106
+    AudioLevels.init();
107
     APP.statistics.addAudioLevelListener(function(jid, audioLevel)
107
     APP.statistics.addAudioLevelListener(function(jid, audioLevel)
108
     {
108
     {
109
         var resourceJid;
109
         var resourceJid;

+ 29
- 28
modules/UI/audio_levels/AudioLevels.js View File

1
 var CanvasUtil = require("./CanvasUtils");
1
 var CanvasUtil = require("./CanvasUtils");
2
 
2
 
3
+var ASDrawContext = $('#activeSpeakerAudioLevel')[0].getContext('2d');
4
+
5
+function initActiveSpeakerAudioLevels() {
6
+    var ASRadius = interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE / 2;
7
+    var ASCenter = (interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE + ASRadius) / 2;
8
+
9
+// Draw a circle.
10
+    ASDrawContext.arc(ASCenter, ASCenter, ASRadius, 0, 2 * Math.PI);
11
+
12
+// Add a shadow around the circle
13
+    ASDrawContext.shadowColor = interfaceConfig.SHADOW_COLOR;
14
+    ASDrawContext.shadowOffsetX = 0;
15
+    ASDrawContext.shadowOffsetY = 0;
16
+}
17
+
3
 /**
18
 /**
4
  * The audio Levels plugin.
19
  * The audio Levels plugin.
5
  */
20
  */
8
 
23
 
9
     my.LOCAL_LEVEL = 'local';
24
     my.LOCAL_LEVEL = 'local';
10
 
25
 
26
+    my.init = function () {
27
+        initActiveSpeakerAudioLevels();
28
+    }
29
+
11
     /**
30
     /**
12
      * Updates the audio level canvas for the given peerJid. If the canvas
31
      * Updates the audio level canvas for the given peerJid. If the canvas
13
      * didn't exist we create it.
32
      * didn't exist we create it.
94
         }
113
         }
95
 
114
 
96
         if(resourceJid  === largeVideoResourceJid) {
115
         if(resourceJid  === largeVideoResourceJid) {
97
-            AudioLevels.updateActiveSpeakerAudioLevel(audioLevel);
116
+            window.requestAnimationFrame(function () {
117
+                AudioLevels.updateActiveSpeakerAudioLevel(audioLevel);
118
+            });
98
         }
119
         }
99
     };
120
     };
100
 
121
 
101
     my.updateActiveSpeakerAudioLevel = function(audioLevel) {
122
     my.updateActiveSpeakerAudioLevel = function(audioLevel) {
102
-        var drawContext = $('#activeSpeakerAudioLevel')[0].getContext('2d');
103
-        var r = interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE / 2;
104
-        var center = (interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE + r) / 2;
123
+        if($("#activeSpeaker").css("visibility") == "hidden")
124
+            return;
105
 
125
 
106
-        // Save the previous state of the context.
107
-        drawContext.save();
108
 
126
 
109
-        drawContext.clearRect(0, 0, 300, 300);
127
+        ASDrawContext.clearRect(0, 0, 300, 300);
128
+        if(audioLevel == 0)
129
+            return;
110
 
130
 
111
-        // Draw a circle.
112
-        drawContext.arc(center, center, r, 0, 2 * Math.PI);
131
+        ASDrawContext.shadowBlur = getShadowLevel(audioLevel);
113
 
132
 
114
-        // Add a shadow around the circle
115
-        drawContext.shadowColor = interfaceConfig.SHADOW_COLOR;
116
-        drawContext.shadowBlur = getShadowLevel(audioLevel);
117
-        drawContext.shadowOffsetX = 0;
118
-        drawContext.shadowOffsetY = 0;
119
 
133
 
120
         // Fill the shape.
134
         // Fill the shape.
121
-        drawContext.fill();
122
-
123
-        drawContext.save();
124
-
125
-        drawContext.restore();
126
-
127
-
128
-        drawContext.arc(center, center, r, 0, 2 * Math.PI);
129
-
130
-        drawContext.clip();
131
-        drawContext.clearRect(0, 0, 277, 200);
132
-
133
-        // Restore the previous context state.
134
-        drawContext.restore();
135
+        ASDrawContext.fill();
135
     };
136
     };
136
 
137
 
137
     /**
138
     /**

+ 29
- 8
modules/statistics/RTPStatsCollector.js View File

111
 PeerStats.prototype.setSsrcAudioLevel = function (ssrc, audioLevel)
111
 PeerStats.prototype.setSsrcAudioLevel = function (ssrc, audioLevel)
112
 {
112
 {
113
     // Range limit 0 - 1
113
     // Range limit 0 - 1
114
-    this.ssrc2AudioLevel[ssrc] = Math.min(Math.max(audioLevel, 0), 1);
114
+    this.ssrc2AudioLevel[ssrc] = formatAudioLevel(audioLevel);
115
 };
115
 };
116
 
116
 
117
+function formatAudioLevel(audioLevel) {
118
+    return Math.min(Math.max(audioLevel, 0), 1);
119
+}
120
+
117
 /**
121
 /**
118
  * Array with the transport information.
122
  * Array with the transport information.
119
  * @type {Array}
123
  * @type {Array}
188
 /**
192
 /**
189
  * Stops stats updates.
193
  * Stops stats updates.
190
  */
194
  */
191
-StatsCollector.prototype.stop = function ()
192
-{
193
-    if (this.audioLevelsIntervalId)
194
-    {
195
+StatsCollector.prototype.stop = function () {
196
+    if (this.audioLevelsIntervalId) {
195
         clearInterval(this.audioLevelsIntervalId);
197
         clearInterval(this.audioLevelsIntervalId);
196
         this.audioLevelsIntervalId = null;
198
         this.audioLevelsIntervalId = null;
199
+    }
200
+
201
+    if (this.statsIntervalId)
202
+    {
197
         clearInterval(this.statsIntervalId);
203
         clearInterval(this.statsIntervalId);
198
         this.statsIntervalId = null;
204
         this.statsIntervalId = null;
205
+    }
206
+
207
+    if(this.logStatsIntervalId)
208
+    {
199
         clearInterval(this.logStatsIntervalId);
209
         clearInterval(this.logStatsIntervalId);
200
         this.logStatsIntervalId = null;
210
         this.logStatsIntervalId = null;
211
+    }
212
+
213
+    if(this.gatherStatsIntervalId)
214
+    {
201
         clearInterval(this.gatherStatsIntervalId);
215
         clearInterval(this.gatherStatsIntervalId);
202
         this.gatherStatsIntervalId = null;
216
         this.gatherStatsIntervalId = null;
203
     }
217
     }
220
 {
234
 {
221
     var self = this;
235
     var self = this;
222
     if(!config.disableAudioLevels) {
236
     if(!config.disableAudioLevels) {
237
+        console.debug("set audio levels interval");
223
         this.audioLevelsIntervalId = setInterval(
238
         this.audioLevelsIntervalId = setInterval(
224
             function () {
239
             function () {
225
                 // Interval updates
240
                 // Interval updates
247
     }
262
     }
248
 
263
 
249
     if(!config.disableStats) {
264
     if(!config.disableStats) {
265
+        console.debug("set stats interval");
250
         this.statsIntervalId = setInterval(
266
         this.statsIntervalId = setInterval(
251
             function () {
267
             function () {
252
                 // Interval updates
268
                 // Interval updates
677
         {
693
         {
678
             // TODO: can't find specs about what this value really is,
694
             // TODO: can't find specs about what this value really is,
679
             // but it seems to vary between 0 and around 32k.
695
             // but it seems to vary between 0 and around 32k.
680
-            audioLevel = audioLevel / 32767;
681
-            jidStats.setSsrcAudioLevel(ssrc, audioLevel);
682
-            if(jid != APP.xmpp.myJid())
696
+            audioLevel = formatAudioLevel(audioLevel / 32767);
697
+            var oldLevel = jidStats.ssrc2AudioLevel[ssrc];
698
+            if(jid != APP.xmpp.myJid() && (!oldLevel || oldLevel != audioLevel))
699
+            {
700
+
701
+                jidStats.ssrc2AudioLevel[ssrc] = audioLevel;
702
+
683
                 this.eventEmitter.emit("statistics.audioLevel", jid, audioLevel);
703
                 this.eventEmitter.emit("statistics.audioLevel", jid, audioLevel);
704
+            }
684
         }
705
         }
685
 
706
 
686
     }
707
     }

+ 1
- 1
modules/statistics/statistics.js View File

48
     if(stream.getOriginalStream().getAudioTracks().length === 0)
48
     if(stream.getOriginalStream().getAudioTracks().length === 0)
49
         return;
49
         return;
50
 
50
 
51
-    localStats = new LocalStats(stream.getOriginalStream(), 100, statistics,
51
+    localStats = new LocalStats(stream.getOriginalStream(), 200, statistics,
52
         eventEmitter);
52
         eventEmitter);
53
     localStats.start();
53
     localStats.start();
54
 }
54
 }

Loading…
Cancel
Save