diff --git a/bbb-api-demo/src/main/webapp/demo_iframe.jsp b/bbb-api-demo/src/main/webapp/demo_iframe.jsp
index 96ca85ce6620a3594da41ba86563c3c89d89a0fb..b5ed66cf6031e7fed5cc391c3b4b54db98ddc318 100644
--- a/bbb-api-demo/src/main/webapp/demo_iframe.jsp
+++ b/bbb-api-demo/src/main/webapp/demo_iframe.jsp
@@ -20,7 +20,6 @@ Authors: James Jung
          Anton Georgiev
 
 -->
-
 <%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
 <%
@@ -134,109 +133,95 @@ if (request.getParameterMap().isEmpty()) {
 %>
 
 <script language="javascript" type="text/javascript">
-	var recButton = document.createElement("button");
-	var muteButton = document.createElement("button");
-
-        //EventListener(Getting message from iframe)
-        window.addEventListener('message', function(e) {
-		handleMessage(e.data.response);
-        });
-
-	function handleMessage(e) {
-		switch(e) {
-		  case 'readyToConnect': {
-		     console.error('readdddy');
-                     // get initial state
-                     getInitialState(); break; }
-		  case 'recordingStarted': { console.log('1'); recButton.innerHTML = "Stop Recording"; break;}
-		  case 'recordingStopped': { console.log('2'); recButton.innerHTML = "Start Recording"; break;}
-		  case 'selfMuted': { console.log('3'); muteButton.innerHTML = "Unmute me"; break;}
-		  case 'selfUnmuted': { console.log('4'); muteButton.innerHTML = "Mute me"; break;}
-		  default: console.log('neither', { e } );
-		}
-
-
-	}
-
-        /********************functions for the controls************************/
-        //Toggle Recording
-        function recToggle(){
-                document.getElementById("client-content").contentWindow.postMessage("c_record","*");
-        }
-
-	// Toggle muting
-	function muteToggle(){
-                document.getElementById("client-content").contentWindow.postMessage("c_mute","*");
-        }
-        ///////////////////////////////////////////////////////////////////////
-
-	function getInitialState() {
-		console.log('getting initial state');
-		document.getElementById("client-content").contentWindow.postMessage("c_recording_status","*");
-	}
 
-        ///////////////////////////////////////////////////////////////////////
+const recButton = document.createElement('button');
+recButton.id = 'recButton';
+const muteButton = document.createElement('button');
+muteButton.id = 'muteButton';
 
-        //Clean up the body node before loading controls and the client
-        document.body.innerHTML = "";
-
-        //Node for the Client
-        var client = document.createElement("div");
-        client.setAttribute("id","client");
+function getInitialState() {
+  document.getElementById('client-content').contentWindow.postMessage('c_recording_status', '*');
+  document.getElementById('client-content').contentWindow.postMessage('c_mute_status', '*');
+}
 
-        var clientContent = document.createElement("iframe");
-        clientContent.setAttribute("id","client-content");
-        // clientContent.setAttribute("src","<%=joinURL%>");
-        // clientContent.setAttribute("src","https://MYDOMAIN.com/demo/demoHTML5.jsp");
-        // clientContent.setAttribute("allow","microphone https://MYDOMAIN.com; camera https://MYDOMAIN.com");
-	clientContent.setAttribute("src","https://anton22.blindside-dev.com/demo/demoHTML5.jsp");
-        clientContent.setAttribute("allow","microphone https://anton22.blindside-dev.com; camera https://anton22.blindside-dev.com");
+function handleMessage(e) {
+  switch (e) {
+    case 'readyToConnect': {
+      // get initial state
+      getInitialState(); break; }
+    case 'recordingStarted': {
+      recButton.innerHTML = 'Stop Recording';
+      break;
+    }
+    case 'recordingStopped': {
+      recButton.innerHTML = 'Start Recording';
+      break;
+    }
+    case 'selfMuted': {
+      muteButton.innerHTML = 'Unmute me';
+      break;
+    }
+    case 'selfUnmuted': {
+      muteButton.innerHTML = 'Mute me';
+      break;
+    }
+    case 'notInAudio': {
+      muteButton.innerHTML = 'Not in audio';
+      document.getElementById('muteButton').disabled = true;
+      break;
+    }
+    case 'joinedAudio': {
+      muteButton.innerHTML = '';
+      document.getElementById('muteButton').disabled = false; getInitialState();
+      break;
+    }
+    default: console.log('neither', { e });
+  }
+}
 
+// EventListener(Getting message from iframe)
+window.addEventListener('message', function(e) {
+  handleMessage(e.data.response);
+});
 
-        client.appendChild(clientContent);
+// Clean up the body node before loading controls and the client
+document.body.innerHTML = '';
 
-        //Node for the Controls
-        var controls = document.createElement("div");
-        controls.setAttribute("id","controls");
-        controls.setAttribute("align","middle");
-        controls.setAttribute("float","left");
+// Node for the Client
+const client = document.createElement('div');
+client.setAttribute('id', 'client');
 
-        /****************** Controls *****************************/
-        //Node for the control which controls recording functionality of the html5Client
-        recButton.setAttribute("onClick","recToggle();");
+const clientContent = document.createElement('iframe');
+clientContent.setAttribute('id', 'client-content');
+clientContent.setAttribute('src','<%=joinURL%>');
+clientContent.setAttribute('src','https://MYDOMAIN.com/demo/demoHTML5.jsp');
+clientContent.setAttribute('allow','microphone https://MYDOMAIN.com; camera https://MYDOMAIN.com');
 
-        controls.appendChild(recButton);
+client.appendChild(clientContent);
 
+// Node for the Controls
+const controls = document.createElement('div');
+controls.setAttribute('id', 'controls');
+controls.setAttribute('align', 'middle');
+controls.setAttribute('float', 'left');
 
-	// var muteButton = document.createElement("button");
-        // muteButton.innerHTML = "Toggle mute";
-        muteButton.setAttribute("onClick","muteToggle();");
+// ****************** Controls *****************************/
+// Node for the control which controls recording functionality of the html5Client
+recButton.setAttribute('onClick', 'recToggle();');
 
-        controls.appendChild(muteButton);
+controls.appendChild(recButton);
 
-        //////////////////////////////////////////////////////////
 
-        //Node for the output screen
-        var output = document.createElement("div");
-        output.setAttribute("id","output");
-        output.setAttribute("align","middle");
+// const muteButton = document.createElement('button');
+// muteButton.innerHTML = 'Toggle mute';
+muteButton.setAttribute('onClick', 'muteToggle();');
 
-        var outputContent = document.createElement("textarea");
-        outputContent.setAttribute("id","output-content");
-        outputContent.setAttribute("rows","2");
-        outputContent.setAttribute("cols","50");
-        output.appendChild(outputContent);
+controls.appendChild(muteButton);
 
-        var currentStates = document.createElement("textarea");
-        currentStates.setAttribute("id","current-states");
-        currentStates.setAttribute("rows","2");
-        currentStates.setAttribute("cols","50");
-        output.appendChild(currentStates);
+// Append the nodes of contents to the body node
+document.body.appendChild(controls);
+document.body.appendChild(client);
 
-        //Append the nodes of contents to the body node
-        document.body.appendChild(controls);
-        document.body.appendChild(output);
-        document.body.appendChild(client);
 </script>
 <%
         } else {
@@ -256,4 +241,3 @@ Error: getJoinURL() failed
 </body>
 </html>
 
-
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx
index 56f37ea82fc5730ae1df0fbe9b8bee913d387f74..ceb0249952521f078d13c67b46c665f86e4f520c 100644
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx
@@ -27,6 +27,7 @@ const intlMessages = defineMessages({
 });
 
 const propTypes = {
+  processToggleMuteFromOutside: PropTypes.func.isRequired,
   handleToggleMuteMicrophone: PropTypes.func.isRequired,
   handleJoinAudio: PropTypes.func.isRequired,
   handleLeaveAudio: PropTypes.func.isRequired,
@@ -45,9 +46,10 @@ const defaultProps = {
 
 class AudioControls extends Component {
   componentDidMount() {
+    const { processToggleMuteFromOutside } = this.props;
     if (Meteor.settings.public.allowOutsideCommands.toggleSelfVoice ||
       getFromUserSettings('outsideToggleSelfVoice', false)) {
-      window.addEventListener('message', this.props.processToggleMuteFromOutside);
+      window.addEventListener('message', processToggleMuteFromOutside);
     }
   }
 
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx
index 0092c384f880eedf56f8938595b1030298587b1b..b2334ede83a8d269b2a0f1313bdae8309f8543db 100644
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx
@@ -10,12 +10,23 @@ import Service from '../service';
 const AudioControlsContainer = props => <AudioControls {...props} />;
 
 const processToggleMuteFromOutside = (e) => {
-  if (e.data === 'c_mute') {
-    const newMuteState = !AudioManager.isMuted;
-    makeCall('toggleSelfVoice')
-      .then(() => {
-        this.window.parent.postMessage({ response: { newMuteState } }, '*');
-      });
+  switch (e.data) {
+    case 'c_mute': {
+      makeCall('toggleSelfVoice');
+      break;
+    }
+    case 'c_mute_status': {
+      if (!AudioManager.isUsingAudio()) {
+        this.window.parent.postMessage({ response: 'notInAudio' }, '*');
+        return;
+      }
+      const muteState = AudioManager.isMuted ? 'selfMuted' : 'selfUnmuted';
+      this.window.parent.postMessage({ response: muteState }, '*');
+      break;
+    }
+    default: {
+      // console.log(e.data);
+    }
   }
 };
 
diff --git a/bigbluebutton-html5/imports/ui/services/audio-manager/index.js b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
index 5bf04b42ef9e002aacd7bcd42c163ae6e015c300..616496c5ca0ee6e0d1fb7f22a04cc8c204a28029 100755
--- a/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
+++ b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
@@ -136,7 +136,7 @@ class AudioManager {
     this.isEchoTest = false;
     const { name } = browser();
     // The kurento bridge isn't a full audio bridge yet, so we have to differ it
-    const bridge = USE_KURENTO ? this.listenOnlyBridge : this.bridge;
+    const bridge = this.useKurento ? this.listenOnlyBridge : this.bridge;
 
     const callOptions = {
       isListenOnly: true,
@@ -146,7 +146,7 @@ class AudioManager {
 
     // Webkit ICE restrictions demand a capture device permission to release
     // host candidates
-    if (name == 'safari') {
+    if (name === 'safari') {
       await this.askDevicesPermissions();
     }
 
@@ -162,12 +162,11 @@ class AudioManager {
       }
 
       logger.error('Listen only error:', err, 'on try', retries);
-      const error = {
+      throw {
         type: 'MEDIA_ERROR',
         message: this.messages.error.MEDIA_ERROR,
-      }
-      throw error;
-    }
+      };
+    };
 
     return this.onAudioJoining()
       .then(() => Promise.race([
@@ -181,14 +180,14 @@ class AudioManager {
             // Exit previous SFU session and clean audio tag state
             window.kurentoExitAudio();
             this.useKurento = false;
-            let audio = document.querySelector(MEDIA_TAG);
+            const audio = document.querySelector(MEDIA_TAG);
             audio.muted = false;
           }
 
           try {
             await this.joinListenOnly(++retries);
-          } catch (err) {
-            return handleListenOnlyError(err);
+          } catch (error) {
+            return handleListenOnlyError(error);
           }
         } else {
           handleListenOnlyError(err);
@@ -207,7 +206,7 @@ class AudioManager {
   exitAudio() {
     if (!this.isConnected) return Promise.resolve();
 
-    const bridge  = (this.useKurento && this.isListenOnly) ? this.listenOnlyBridge : this.bridge;
+    const bridge = (this.useKurento && this.isListenOnly) ? this.listenOnlyBridge : this.bridge;
 
     this.isHangingUp = true;
     this.isEchoTest = false;
@@ -235,6 +234,12 @@ class AudioManager {
         changed: (id, fields) => {
           if (fields.muted !== undefined && fields.muted !== this.isMuted) {
             this.isMuted = fields.muted;
+            const muteState = this.isMuted ? 'selfMuted' : 'selfUnmuted';
+            window.parent.postMessage({ response: muteState }, '*');
+          }
+
+          if (fields.joined) {
+            window.parent.postMessage({ response: 'joinedAudio' }, '*');
           }
 
           if (fields.talking !== undefined && fields.talking !== this.isTalking) {
@@ -313,17 +318,14 @@ class AudioManager {
       new window.AudioContext() :
       new window.webkitAudioContext();
 
-    // Create a placeholder buffer to upstart audio context
-    const pBuffer = this.listenOnlyAudioContext.createBuffer(2, this.listenOnlyAudioContext.sampleRate * 3, this.listenOnlyAudioContext.sampleRate);
-
-    var dest = this.listenOnlyAudioContext.createMediaStreamDestination();
+    const dest = this.listenOnlyAudioContext.createMediaStreamDestination();
 
-    let audio = document.querySelector(MEDIA_TAG);
+    const audio = document.querySelector(MEDIA_TAG);
 
     // Play bogus silent audio to try to circumvent autoplay policy on Safari
-    audio.src = 'resources/sounds/silence.mp3'
+    audio.src = 'resources/sounds/silence.mp3';
 
-    audio.play().catch(e => {
+    audio.play().catch((e) => {
       logger.warn('Error on playing test audio:', e);
     });