This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openmeetings.git


The following commit(s) were added to refs/heads/master by this push:
     new a5fb3ae  [OPENMEETINGS-2029] audio/video should work better
a5fb3ae is described below

commit a5fb3ae0e1cd0cacb2355a5c918859cbf5691a29
Author: Maxim Solodovnik <solomax...@gmail.com>
AuthorDate: Tue Mar 12 23:47:47 2019 +0700

    [OPENMEETINGS-2029] audio/video should work better
---
 .../apache/openmeetings/web/room/RoomPanel.html    |  2 +-
 .../openmeetings/web/room/VideoSettings.html       |  2 +-
 .../apache/openmeetings/web/room/kurento-utils.js  |  4 +-
 .../apache/openmeetings/web/room/raw-settings.js   | 82 +++++++++++++++-------
 .../org/apache/openmeetings/web/room/raw-video.js  | 45 +++++++-----
 openmeetings-web/src/main/webapp/css/raw-room.css  | 15 +---
 .../src/main/webapp/css/raw-variables.css          |  1 +
 7 files changed, 89 insertions(+), 62 deletions(-)

diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
index 15f281a..50ded0c 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
@@ -43,7 +43,7 @@
        <div style="display:none">
                <div id="user-video">
                        <div class="video">
-                               <div class="level-meter" 
wicket:message="title:767"></div>
+                               <canvas width="10" class="level-meter" 
wicket:message="title:767"></canvas>
                                <div class="mute-others" 
wicket:message="title:video.muteothers"></div>
                        </div>
                        <div class="footer ui-state-highlight">
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.html
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.html
index ab04f44..4fbce9c 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.html
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.html
@@ -70,7 +70,7 @@
                                <div class="video-conainer">
                                        <video autoplay="autoplay"></video>
                                </div>
-                               <div class="level-meter" 
wicket:message="title:767"></div>
+                               <canvas class="level-meter" 
data-orientation="horizontal" wicket:message="title:767" width="250" 
height="16"></canvas>
                                <div class="sett-row right">
                                        <div class="timer 
ui-widget-header"><span class="time"></span>&nbsp;<wicket:message 
key="network.test.sec"/></div>
                                        <div><button 
class="play"><wicket:message key="764"/></button></div>
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/kurento-utils.js
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/kurento-utils.js
index f4bad72..3c1fc36 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/kurento-utils.js
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/kurento-utils.js
@@ -400,12 +400,12 @@ function WebRtcPeer(mode, options, callback) {
         }
         if (videoStream) {
             videoStream.getTracks().forEach(function(track) {
-                pc.addTrack(track);
+                pc.addTrack(track, videoStream);
             });
         }
         if (audioStream) {
             audioStream.getTracks().forEach(function(track) {
-                pc.addTrack(track);
+                pc.addTrack(track, audioStream);
             });
         }
         var browser = parser.getBrowser();
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-settings.js
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-settings.js
index 8fcebb0..704c197 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-settings.js
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-settings.js
@@ -14,9 +14,9 @@ $.widget('openmeetings.iconselectmenu', $.ui.selectmenu, {
        }
 });
 var MicLevel = (function() {
-       let ctx, mic, script, vol = .0;
+       let ctx, mic, analyser, vol = .0;
 
-       function _meter(rtcPeer, _micActivity, _error) {
+       function _meterPeer(rtcPeer, cnvs, _micActivity, _error) {
                if (!rtcPeer || 'function' !== typeof(rtcPeer.getLocalStream)) {
                        return;
                }
@@ -25,28 +25,55 @@ var MicLevel = (function() {
                        return;
                }
                try {
-                       ctx = new AudioContext();
-                       script = ctx.createScriptProcessor(512);
+                       const AudioCtx = window.AudioContext || 
window.webkitAudioContext;
+                       if (!AudioCtx) {
+                               _error("AudioContext is inaccessible");
+                               return;
+                       }
+                       ctx = new AudioCtx();
+                       analyser = ctx.createAnalyser();
                        mic = ctx.createMediaStreamSource(stream);
-                       mic.connect(script);
-                       script.connect(ctx.destination);
-                       let t = Date.now();
-                       script.onaudioprocess = function(event) {
-                               const arr = event.inputBuffer.getChannelData(0)
-                                       , al = arr.length;
-                               let avg = 0.0;
-                               for (let i = 0; i < al; ++i) {
-                                       avg += arr[i] * arr[i];
-                               }
-                               avg = Math.sqrt(avg / al);
-                               vol = Math.max(avg, vol * .95);
-                               //we will continuously get volume but do not 
perform re-draw too often
-                               if (Date.now() - t < 200) {
-                                       return;
+                       mic.connect(analyser);
+                       analyser.connect(ctx.destination);
+                       _meter(analyser, cnvs, _micActivity, _error);
+               } catch (err) {
+                       _error(err);
+               }
+       }
+       function _meter(analyser, cnvs, _micActivity, _error) {
+               try {
+                       analyser.minDecibels = -90;
+                       analyser.maxDecibels = -10;
+                       analyser.fftSize = 256;
+                       const canvas = cnvs[0]
+                               , color = $('body').css('--level-color')
+                               , canvasCtx = canvas.getContext('2d')
+                               , al = analyser.frequencyBinCount
+                               , arr = new Uint8Array(al)
+                               , horiz = cnvs.data('orientation') === 
'horizontal';
+                       function update() {
+                               const WIDTH = canvas.width
+                                       , HEIGHT = canvas.height;
+                               canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);
+                               if (!!analyser && cnvs.is(':visible')) {
+                                       analyser.getByteFrequencyData(arr);
+                                       let favg = 0.0;
+                                       for (let i = 0; i < al; ++i) {
+                                               favg += arr[i] * arr[i];
+                                       }
+                                       vol = Math.sqrt(favg / al);
+                                       _micActivity(vol);
+                                       canvasCtx.fillStyle = color;
+                                       if (horiz) {
+                                               canvasCtx.fillRect(0, 0, WIDTH 
* vol / 100, HEIGHT);
+                                       } else {
+                                               const h = HEIGHT * vol / 100;
+                                               canvasCtx.fillRect(0, HEIGHT - 
h, WIDTH, h);
+                                       }
+                                       requestAnimationFrame(update);
                                }
-                               t = Date.now();
-                               _micActivity(vol);
-                       };
+                       }
+                       update();
                } catch (err) {
                        _error(err);
                }
@@ -56,14 +83,17 @@ var MicLevel = (function() {
                        VideoUtil.cleanStream(mic.mediaStream);
                        mic.disconnect();
                        ctx.destination.disconnect();
-                       script.disconnect();
-                       script.onaudioprocess = null;
                        ctx.close();
                        ctx = null;
                }
+               if (!!analyser) {
+                       analyser.disconnect();
+                       analyser = null;
+               }
        }
        return {
                meter: _meter
+               , meterPeer: _meterPeer
                , dispose: _dispose
        };
 });
@@ -205,7 +235,6 @@ var VideoSettings = (function() {
                                _close();
                        }
                });
-               lm.kendoProgressBar({ value: 0, showStatus: false });
                o.width = 300;
                o.height = 200;
                o.mode = 'settings';
@@ -304,7 +333,7 @@ var VideoSettings = (function() {
                                                        return 
OmUtil.error(error);
                                                }
                                                level = MicLevel();
-                                               level.meter(rtcPeer, 
_micActivity, OmUtil.error);
+                                               level.meterPeer(rtcPeer, lm, 
_micActivity, OmUtil.error);
                                                
rtcPeer.generateOffer(function(error, _offerSdp) {
                                                        if (error) {
                                                                return 
OmUtil.error('Error generating the offer');
@@ -328,7 +357,6 @@ var VideoSettings = (function() {
                _updateRec();
        }
        function _micActivity(level) {
-               lm.getKendoProgressBar().value(140 * level); // magic number
        }
        function _setLoading(el) {
                el.find('option').remove();
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video.js 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video.js
index 79897fe..201c71d 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video.js
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video.js
@@ -1,8 +1,9 @@
 /* Licensed under the Apache License, Version 2.0 (the "License") 
http://www.apache.org/licenses/LICENSE-2.0 */
 var Video = (function() {
-       const self = {};
+       const self = {}
+               , AudioCtx = window.AudioContext || window.webkitAudioContext;
        let sd, v, vc, t, f, size, vol, slider, handle, video, rtcPeer
-               , lastVolume = 50, muted = false, aCtx, aSrc, aDest, gainNode
+               , lastVolume = 50, muted = false, aCtx, aSrc, aDest, gainNode, 
analyser
                , lm, level, userSpeaks = false, muteOthers;
 
        function _getExtra() {
@@ -21,16 +22,19 @@ var Video = (function() {
                        , pw = p.width(), ph = p.height();
                _resizeDlgArea(pw, ph);
        }
-       function _resize(w, h) {
-               vc.width(w).height(h);
+       function _resizeLm(h) {
                if (!!lm) {
-                       lm.height(h - 10);
+                       lm.attr('height', h).height(h);
                }
+               return lm;
+       }
+       function _resize(w, h) {
+               vc.width(w).height(h);
+               _resizeLm(h - 10);
                video.width(w).height(h);
        }
        function _micActivity(level) {
-               lm.getKendoProgressBar().value(140 * level); // magic number
-               const speaks = level > .02;
+               const speaks = level > 5;
                if (speaks !== userSpeaks) {
                        userSpeaks = speaks;
                        OmUtil.sendMessage({type: 'mic', id: 'activity', 
active: speaks});
@@ -90,18 +94,19 @@ var Video = (function() {
                                        let _stream = stream;
                                        if (stream.getAudioTracks().length !== 
0) {
                                                vol.show();
-                                               lm = vc.find('.level-meter')
-                                                       .kendoProgressBar({ 
value: 0, showStatus: false, orientation: 'vertical' });
-                                               lm.height(vc.height() - 
10).show();
-                                               aCtx = new AudioContext();
+                                               lm = vc.find('.level-meter');
+                                               _resizeLm(vc.height() - 
10).show();
+                                               aCtx = new AudioCtx();
                                                gainNode = aCtx.createGain();
+                                               analyser = 
aCtx.createAnalyser();
                                                aSrc = 
aCtx.createMediaStreamSource(stream);
                                                aSrc.connect(gainNode);
+                                               gainNode.connect(analyser);
                                                if (VideoUtil.isEdge()) {
-                                                       
gainNode.connect(aCtx.destination);
+                                                       
analyser.connect(aCtx.destination);
                                                } else {
                                                        aDest = 
aCtx.createMediaStreamDestination();
-                                                       gainNode.connect(aDest);
+                                                       analyser.connect(aDest);
                                                        aSrc.origStream = 
stream;
                                                        _stream = aDest.stream;
                                                        
stream.getVideoTracks().forEach(function(track) {
@@ -133,7 +138,7 @@ var Video = (function() {
                                        return OmUtil.error(error);
                                }
                                level = MicLevel();
-                               level.meter(rtcPeer, _micActivity, 
OmUtil.error);
+                               level.meter(analyser, lm, _micActivity, 
OmUtil.error);
                                this.generateOffer(function(error, offerSdp) {
                                        if (error) {
                                                return OmUtil.error('Sender sdp 
offer error ' + error);
@@ -441,6 +446,10 @@ var Video = (function() {
        }
        function _cleanup() {
                OmUtil.log('Disposing participant ' + sd.uid);
+               if (!!analyser) {
+                       analyser.disconnect();
+                       analyser = null;
+               }
                if (!!gainNode) {
                        gainNode.disconnect();
                        gainNode = null;
@@ -463,9 +472,11 @@ var Video = (function() {
                        aCtx = null;
                }
                if (!!video && video.length > 0) {
-                       VideoUtil.cleanStream(video[0].srcObject);
-                       video[0].srcObject = null;
-                       video.remove();
+                       video.attr('id', 'dummy');
+                       const vidNode = video[0];
+                       VideoUtil.cleanStream(vidNode.srcObject);
+                       vidNode.srcObject = null;
+                       vidNode.parentNode.removeChild(vidNode);
                        video = null;
                }
                if (!!lm && lm.length > 0) {
diff --git a/openmeetings-web/src/main/webapp/css/raw-room.css 
b/openmeetings-web/src/main/webapp/css/raw-room.css
index 7337177..c40ceed 100644
--- a/openmeetings-web/src/main/webapp/css/raw-room.css
+++ b/openmeetings-web/src/main/webapp/css/raw-room.css
@@ -282,26 +282,16 @@ ul.settings-menu {
        min-width: 300px;
        padding-left: 305px;
 }
-#video-settings .level-meter {
-       height: 16px;
-}
 .ui-dialog.video .warn {
        float: right;
        margin-right: .3em;
 }
-.level-meter.k-progressbar .k-state-selected {
-       background: greenyellow;
-       border-color: #d5d5d5;
-}
-.ui-dialog.video .level-meter {
-       background: transparent;
-}
 .ui-dialog.user-video .level-meter {
        display: inline-block;
-       width: 10px;
        position: absolute;
        bottom: 5px;
        left: 5px;
+       width: 10px;
 }
 .ui-dialog.video .sett-container {
        position: relative;
@@ -322,9 +312,6 @@ ul.settings-menu {
        float: left;
        padding: 2px 4px;
 }
-.ui-dialog.video .sett-row select, #video-settings .level-meter {
-       width: 250px;
-}
 .ui-dialog.video .ui-dialog-titlebar-collapse span
 , .ui-dialog.video .ui-dialog-titlebar-volume span
 , .ui-dialog.video .ui-dialog-titlebar-refresh span
diff --git a/openmeetings-web/src/main/webapp/css/raw-variables.css 
b/openmeetings-web/src/main/webapp/css/raw-variables.css
index dc2552f..a7e8679 100644
--- a/openmeetings-web/src/main/webapp/css/raw-variables.css
+++ b/openmeetings-web/src/main/webapp/css/raw-variables.css
@@ -19,6 +19,7 @@
 body {
        --header-height: 50px;
        --menu-height: 36px;
+       --level-color: greenyellow;
 }
 body.no-header {
        --header-height: 0px;

Reply via email to