diff options
author | Daniel Calviño Sánchez <danxuliu@gmail.com> | 2019-07-19 18:55:37 +0300 |
---|---|---|
committer | Daniel Calviño Sánchez <danxuliu@gmail.com> | 2019-07-19 19:10:29 +0300 |
commit | 0e9dc43640719df7d45e4556ada9d20ae0bead94 (patch) | |
tree | dd35aed6bc9816d40a4fa177a1130d315ac4a5e4 | |
parent | 28da26d2930a04398ec6f2024c10d1d660b84bb1 (diff) |
Add volume indicator for the local audio
The volume is shown as a vertical bar next to the audio icon that grows
and shrinks (with a fixed bottom position) depending on the volume
level. The bar is coloured with a gradient from green to yellow to red
for better clarity of the current volume.
The previous way of indicating speech (a pulse animation in the audio
icon) has not been modified; this is an additional visualization (only
for the local audio) to provide a more noticeable feedback to the user.
Both the existing button and the new bar had to be wrapped in a helper
div to include the volume bar in the old layout.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
-rw-r--r-- | css/video.scss | 27 | ||||
-rw-r--r-- | js/views/mediacontrolsview.js | 23 | ||||
-rw-r--r-- | js/views/templates.js | 4 | ||||
-rw-r--r-- | js/views/templates/mediacontrolsview.handlebars | 5 |
4 files changed, 56 insertions, 3 deletions
diff --git a/css/video.scss b/css/video.scss index 8a0d909a4..981e50b4e 100644 --- a/css/video.scss +++ b/css/video.scss @@ -446,3 +446,30 @@ video { opacity: 1; } } + + + +#muteWrapper { + display: inline-block; + + /* Make the wrapper the positioning context of the volume indicator. */ + position: relative; +} + +#muteWrapper .volume-indicator { + position: absolute; + + width: 3px; + right: 0px; + + /* The button height is 44px; the volume indicator button is 36px at + * maximum, but its value will be changed based on the current volume; the + * height change will reveal more or less of the gradient, which has + * absolute dimensions and thus does not change when the height changes. */ + height: 36px; + bottom: 4px; + + background: linear-gradient(0deg, green, yellow, red 36px); + + opacity: 0.7; +} diff --git a/js/views/mediacontrolsview.js b/js/views/mediacontrolsview.js index 5335af592..58f26ec84 100644 --- a/js/views/mediacontrolsview.js +++ b/js/views/mediacontrolsview.js @@ -56,6 +56,7 @@ ui: { 'audioButton': '#mute', + 'volumeIndicator': '#muteWrapper .volume-indicator', 'videoButton': '#hideVideo', 'screensharingButton': '#screensharing-button', 'screensharingMenu': '#screensharing-menu', @@ -84,6 +85,8 @@ this._webrtc = options.webrtc; this._sharedScreens = options.sharedScreens; + this._handleVolumeChangeBound = this._handleVolumeChange.bind(this); + this._audioAvailable = true; this._videoAvailable = true; @@ -92,7 +95,13 @@ }, setWebRtc: function(webrtc) { + if (this._webrtc && this._webrtc.webrtc) { + this._webrtc.webrtc.off('volumeChange', this._handleVolumeChangeBound); + } + this._webrtc = webrtc; + + this._webrtc.webrtc.on('volumeChange', this._handleVolumeChangeBound); }, setSharedScreens: function(sharedScreens) { @@ -153,6 +162,20 @@ this._audioAvailable = audioAvailable; }, + _handleVolumeChange: function(currentVolume, threshold) { + // WebRTC volume goes from -100 (silence) to 0 (loudest sound in the + // system); for the volume indicator only sounds above the threshold + // are taken into account. + var currentVolumeProportion = 0; + if (currentVolume > threshold) { + currentVolumeProportion = (threshold - currentVolume) / threshold; + } + + var maximumVolumeIndicatorHeight = this.getUI('volumeIndicator').parent().outerHeight() - (parseInt(this.getUI('volumeIndicator').css('bottom'), 10) * 2); + + this.getUI('volumeIndicator').height(maximumVolumeIndicatorHeight * currentVolumeProportion); + }, + toggleVideo: function() { if (!this._videoAvailable) { return; diff --git a/js/views/templates.js b/js/views/templates.js index bd497b66e..f88adf8c8 100644 --- a/js/views/templates.js +++ b/js/views/templates.js @@ -243,9 +243,9 @@ templates['localvideoview'] = template({"compiler":[7,">= 4.0.0"],"main":functio templates['mediacontrolsview'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; - return "<button id=\"mute\" class=\"icon-audio force-icon-white-in-call icon-shadow\" data-placement=\"top\" data-toggle=\"tooltip\" data-original-title=\"" + return "<div id=\"muteWrapper\">\n <button id=\"mute\" class=\"icon-audio force-icon-white-in-call icon-shadow\" data-placement=\"top\" data-toggle=\"tooltip\" data-original-title=\"" + alias4(((helper = (helper = helpers.muteAudioButtonTitle || (depth0 != null ? depth0.muteAudioButtonTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"muteAudioButtonTitle","hash":{},"data":data}) : helper))) - + "\"></button>\n<button id=\"hideVideo\" class=\"icon-video force-icon-white-in-call icon-shadow\" data-placement=\"top\" data-toggle=\"tooltip\" data-original-title=\"" + + "\"></button>\n <span class=\"volume-indicator\"></span>\n</div>\n<button id=\"hideVideo\" class=\"icon-video force-icon-white-in-call icon-shadow\" data-placement=\"top\" data-toggle=\"tooltip\" data-original-title=\"" + alias4(((helper = (helper = helpers.hideVideoButtonTitle || (depth0 != null ? depth0.hideVideoButtonTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"hideVideoButtonTitle","hash":{},"data":data}) : helper))) + "\"></button>\n<button id=\"screensharing-button\" class=\"app-navigation-entry-utils-menu-button icon-screen-off force-icon-white-in-call icon-shadow screensharing-disabled\" data-placement=\"top\" data-toggle=\"tooltip\" data-original-title=\"" + alias4(((helper = (helper = helpers.screensharingButtonTitle || (depth0 != null ? depth0.screensharingButtonTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"screensharingButtonTitle","hash":{},"data":data}) : helper))) diff --git a/js/views/templates/mediacontrolsview.handlebars b/js/views/templates/mediacontrolsview.handlebars index b6c0e58c5..593667139 100644 --- a/js/views/templates/mediacontrolsview.handlebars +++ b/js/views/templates/mediacontrolsview.handlebars @@ -1,4 +1,7 @@ -<button id="mute" class="icon-audio force-icon-white-in-call icon-shadow" data-placement="top" data-toggle="tooltip" data-original-title="{{muteAudioButtonTitle}}"></button> +<div id="muteWrapper"> + <button id="mute" class="icon-audio force-icon-white-in-call icon-shadow" data-placement="top" data-toggle="tooltip" data-original-title="{{muteAudioButtonTitle}}"></button> + <span class="volume-indicator"></span> +</div> <button id="hideVideo" class="icon-video force-icon-white-in-call icon-shadow" data-placement="top" data-toggle="tooltip" data-original-title="{{hideVideoButtonTitle}}"></button> <button id="screensharing-button" class="app-navigation-entry-utils-menu-button icon-screen-off force-icon-white-in-call icon-shadow screensharing-disabled" data-placement="top" data-toggle="tooltip" data-original-title="{{screensharingButtonTitle}}"></button> <div id="screensharing-menu" class="app-navigation-entry-menu"> |