diff --git a/bigbluebutton-html5/imports/api/2.0/audio/client/bridge/sip.js b/bigbluebutton-html5/imports/api/2.0/audio/client/bridge/sip.js
index 81b9825f44a6aed5eb0630cf706a18859af35e41..3401d72dbabd4adac3a6b2b947a5ccc3c2d1aab0 100755
--- a/bigbluebutton-html5/imports/api/2.0/audio/client/bridge/sip.js
+++ b/bigbluebutton-html5/imports/api/2.0/audio/client/bridge/sip.js
@@ -14,12 +14,14 @@ export default class SIPBridge extends BaseAudioBridge {
   }
 
   joinListenOnly(stunServers, turnServers, callbackFromManager) {
+    console.log('Join listen only from sip');
     makeCall('listenOnlyToggle', true);
-    this._joinVoiceCallSIP({ isListenOnly: true }, stunServers, turnServers, callbackFromManager);
+    return this._joinVoiceCallSIP({ isListenOnly: true }, stunServers, turnServers, callbackFromManager);
   }
 
   joinMicrophone(stunServers, turnServers, callbackFromManager) {
-    this._joinVoiceCallSIP({ isListenOnly: false }, stunServers, turnServers, callbackFromManager);
+    console.log('Join microphone from sip');
+    return this._joinVoiceCallSIP({ isListenOnly: false }, stunServers, turnServers, callbackFromManager);
   }
 
   // Periodically check the status of the WebRTC call, when a call has been established attempt to
@@ -67,19 +69,27 @@ export default class SIPBridge extends BaseAudioBridge {
 
   // join the conference. If listen only send the request to the server
   _joinVoiceCallSIP(options, stunServers, turnServers, callbackFromManager) {
-    const extension = this.userData.voiceBridge;
-    console.log(options);
-
-    // create voice call params
-    const joinCallback = function (message) {
-      console.log('Beginning WebRTC Conference Call');
-    };
-
-    const stunsAndTurns = {
-      stun: stunServers,
-      turn: turnServers,
-    };
+    return new Promise((resolve, reject) => {
+      const extension = this.userData.voiceBridge;
+      console.log(options);
+
+      // create voice call params
+      const joinCallback = function (message) {
+        console.log('Beginning WebRTC Conference Call', this.userData);
+      };
+
+      const stunsAndTurns = {
+        stun: stunServers,
+        turn: turnServers,
+      };
+
+      const callback = (message) => {
+        console.log('CALLBACK FROM SIP BRIDGE');
+        return callbackFromManager(message).then(response => resolve(response))
+                       .catch(reason => reject(reason));
+      }
 
-    callIntoConference(extension, callbackFromManager, options.isListenOnly, stunsAndTurns);
+      callIntoConference(extension, callback, options.isListenOnly, stunsAndTurns);
+    })
   }
 }
diff --git a/bigbluebutton-html5/imports/api/2.0/audio/client/manager/index.js b/bigbluebutton-html5/imports/api/2.0/audio/client/manager/index.js
index 81e9d19ea6ed5d01793291918005fe92e91973ed..02a4193c5fec4d41b97473b3dd3d2a81141c531c 100755
--- a/bigbluebutton-html5/imports/api/2.0/audio/client/manager/index.js
+++ b/bigbluebutton-html5/imports/api/2.0/audio/client/manager/index.js
@@ -77,45 +77,59 @@ class AudioManager {
       throw 'Audio Bridge not compatible';
     }
 
+    console.log('INIT AUDIO MANAGER', audioBridge);
+
     this.bridge = audioBridge;
     this.isListenOnly = false;
     this.microphoneLockEnforced = userData.microphoneLockEnforced;
     this.callStates = CallStates;
     this.currentState = this.callStates.init;
 
-    callbackToAudioBridge = function (message) {
-      switch (message.status) {
-        case 'failed': {
-          this.currentState = this.callStates.init;
-          const audioFailed = new CustomEvent('bbb.webrtc.failed', {
-            detail: {
-              status: 'Failed',
-              errorCode: message.errorcode,
-            },
-          });
-          window.dispatchEvent(audioFailed);
-          break;
-        }
-        case 'mediafail': {
-          const mediaFailed = new CustomEvent('bbb.webrtc.mediaFailed', {
-            detail: {
-              status: 'MediaFailed',
-            },
-          });
-          window.dispatchEvent(mediaFailed);
-          break;
-        }
-        case 'mediasuccess':
-        case 'started': {
-          const connected = new CustomEvent('bbb.webrtc.connected', {
-            detail: {
-              status: 'started',
-            },
-          });
-          window.dispatchEvent(connected);
-          break;
+    callbackToAudioBridge = (message) => {
+      return new Promise((resolve, reject) => {
+        console.log('MESSAGE', message);
+        if(message.status === 'failed' || message.status === 'mediafail') {
+          console.log('REJECT FROM MANAGER CALLBACK');
+          reject(message.status);
+        } else if (message.status === 'started'){
+          console.log('RESOLVE FROM MANAGER CALLBACK');
+          resolve(message.status)
         }
-      }
+      })
+
+      // switch (message.status) {
+      //   case 'failed': {
+      //     this.currentState = this.callStates.init;
+      //     const audioFailed = new CustomEvent('bbb.webrtc.failed', {
+      //       detail: {
+      //         status: 'Failed',
+      //         errorCode: message.errorcode,
+      //       },
+      //     });
+      //     window.dispatchEvent(audioFailed);
+      //     break;
+      //   }
+      //   case 'mediafail': {
+      //     const mediaFailed = new CustomEvent('bbb.webrtc.mediaFailed', {
+      //       detail: {
+      //         status: 'MediaFailed',
+      //       },
+      //     });
+      //     window.dispatchEvent(mediaFailed);
+      //     break;
+      //   }
+      //   case 'mediasuccess':
+      //   case 'started': {
+      //     const connected = new CustomEvent('bbb.webrtc.connected', {
+      //       detail: {
+      //         status: 'started',
+      //       },
+      //     });
+      //     window.dispatchEvent(connected);
+      //
+      //     break;
+      //   }
+      // }
     };
   }
 
@@ -129,25 +143,28 @@ class AudioManager {
   }
 
   joinAudio(listenOnly) {
-    AudioManager.fetchServers().then(({ error, stunServers, turnServers }) => {
-      if (error || error !== undefined) {
-        // We need to alert the user about this problem by some gui message.
-        console.error("Couldn't fetch the stuns/turns servers!");
+    return new Promise((resolve, reject) => {
+      AudioManager.fetchServers().then(({ stunServers, turnServers }) => {
+        const shouldJoinListenOnly = listenOnly || this.microphoneLockEnforced;
+
+        if (shouldJoinListenOnly) {
+          this.bridge.joinListenOnly(stunServers, turnServers, callbackToAudioBridge.bind(this)).then((response) => {
+            this.isListenOnly = true;
+            this.currentState = this.callStates.inListenOnly;
+            resolve(response);
+          }).catch(reason => reject(reason));
+        } else {
+          this.bridge.joinMicrophone(stunServers, turnServers, callbackToAudioBridge.bind(this)).then((response) => {
+            this.currentState = this.callStates.inConference;
+            resolve(response);
+          }).catch(reason => reject(reason));
+        }
+      }).catch(error => {
         AudioManager.stunTurnServerFail();
-        return;
-      }
-
-      if (listenOnly || this.microphoneLockEnforced) {
-        this.isListenOnly = true;
-        this.bridge.joinListenOnly(stunServers, turnServers, callbackToAudioBridge.bind(this));
-        // TODO: remove line below after echo test implemented, use webRTCCallStarted instead
-        this.currentState = this.callStates.inListenOnly;
-      } else {
-        this.bridge.joinMicrophone(stunServers, turnServers, callbackToAudioBridge.bind(this));
-        // TODO: remove line below after echo test implemented, use webRTCCallStarted instead
-        this.currentState = this.callStates.inConference;
-      }
-    });
+        console.error(error);
+        reject(error);
+      });
+    })
   }
 
   transferToConference() {
@@ -207,7 +224,7 @@ class AudioManager {
   // We use on the SIP an String Array, while in the server, it comes as
   // an Array of objects, we need to map from Array<Object> to Array<String>
   static mapToArray({ response, stunServers, turnServers }) {
-    const promise = new Promise((resolve) => {
+    return new Promise((resolve) => {
       if (response) {
         resolve({ error: 404, stunServers: [], turnServers: [] });
       }
@@ -216,15 +233,19 @@ class AudioManager {
         turnServers: turnServers.map(server => server.url),
       });
     });
-    return promise;
   }
 
   static fetchServers() {
-    const url = `/bigbluebutton/api/stuns?sessionToken=${Auth.sessionToken}`;
+    return new Promise(async (resolve, reject) => {
+      const url = `/bigbluebutton/api/stuns?sessionToken=${Auth.sessionToken}`;
+
+      let response = await fetch(url)
+        .then(response => response.json())
+        .then(json => AudioManager.mapToArray(json));
 
-    return fetch(url)
-      .then(response => response.json())
-      .then(json => AudioManager.mapToArray(json));
+      if(response.error) return reject(`Could not fetch the stuns/turns servers!`);
+      resolve(response);
+    })
   }
 }
 
diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx
index 31b73bb67719318aa38f1cfe07141de3a6a87a77..33b7fda1696edec096fcb5ef5fa7daf419893ba9 100644
--- a/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx
@@ -2,8 +2,9 @@ import React, { Component } from 'react';
 import styles from './styles.scss';
 import EmojiContainer from './emoji-menu/container';
 import ActionsDropdown from './actions-dropdown/component';
+
+import AudioControlsContainer from '../audio/audio-controls/container';
 import JoinAudioOptionsContainer from '../audio/audio-menu/container';
-import MuteAudioContainer from './mute-button/container';
 
 export default class ActionsBar extends Component {
   constructor(props) {
@@ -19,12 +20,13 @@ export default class ActionsBar extends Component {
           <ActionsDropdown {...{ isUserPresenter }} />
         </div>
         <div className={styles.center}>
-          <MuteAudioContainer />
+          <AudioControlsContainer/>
+          {/*
           <JoinAudioOptionsContainer
             handleJoinAudio={this.props.handleOpenJoinAudio}
             handleCloseAudio={this.props.handleExitAudio}
           />
-          {/* <JoinVideo />*/}
+           <JoinVideo />*/}
           <EmojiContainer />
         </div>
       </div>
diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx
index 9a19d36810b2a0c4098dca4581a42f0356cbbbaa..881981d9bdb154982cbc3968f6f13b97069c83b0 100755
--- a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx
@@ -8,10 +8,6 @@ import AudioService from '../audio/service';
 import AudioModal from '../audio/audio-modal/component';
 
 class ActionsBarContainer extends Component {
-  constructor(props) {
-    super(props);
-  }
-
   render() {
     return (
       <ActionsBar
diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/styles.scss b/bigbluebutton-html5/imports/ui/components/actions-bar/styles.scss
index b74ee7dfa20d98d04c4c65c2cabcd73f2cd340e3..dbea4fdf5f5e29ee97d4a60e1b58ce12d6a4e679 100755
--- a/bigbluebutton-html5/imports/ui/components/actions-bar/styles.scss
+++ b/bigbluebutton-html5/imports/ui/components/actions-bar/styles.scss
@@ -24,7 +24,3 @@
 .center {
   align-items: center;
 }
-
-.circleGlow > :first-child{
-    box-shadow: 0 0 .15rem #FFF !important;
-}
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..f9d05dfe50968c6bd408f20873e82b3fc61e0b05
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx
@@ -0,0 +1,34 @@
+import React, { Component } from 'react';
+import MuteAudioContainer from '../mute-button/container';
+import OpenAudioModalButton from '../open-audio-modal-button/container';
+import styles from './styles.scss';
+import Button from '/imports/ui/components/button/component';
+
+
+export default ({
+  handleToggleMuteMicrophone,
+  handleJoinAudio,
+  handleLeaveAudio,
+  mute,
+  unmute,
+  join,
+ }) => (
+  <span className={styles.container}>
+    {mute ?
+      <Button
+        onClick={handleToggleMuteMicrophone}
+        label={unmute ? 'Unmute' : 'Mute'}
+        color={'primary'}
+        icon={unmute ? 'mute' : 'unmute'}
+        size={'lg'}
+        circle
+      /> : null}
+    <Button
+      onClick={ join ? handleLeaveAudio : handleJoinAudio }
+      label={ join ? 'Leave Audio' : 'Join Audio'}
+      color={ join ? 'danger' : 'primary' }
+      icon={ join ? 'audio_off' : 'audio_on' }
+      size={'lg'}
+      circle
+    />
+  </span>);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..05d9135731d740022b28e323e96711f1e65b48f4
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import { createContainer } from 'meteor/react-meteor-data';
+import PropTypes from 'prop-types';
+import AudioControls from './component';
+import Service from '../service';
+
+// const propTypes = {
+//   children: PropTypes.element,
+// };
+//
+// const defaultProps = {
+//   children: null,
+// };
+
+const AudioControlsContainer = props => <AudioControls {...props} />
+
+let didMountAutoJoin = false;
+
+export default createContainer(() => {
+  // const APP_CONFIG = Meteor.settings.public.app;
+  //
+  // const { autoJoinAudio } = APP_CONFIG;
+  // const { isConnected, isConnecting, isListenOnly } = Service.getStats();
+  // let shouldShowMute = isConnected && !isListenOnly;
+  // let shouldShowUnmute = isConnected && !isListenOnly && isMuted;
+  // let shouldShowJoin = !isConnected;
+
+  return {
+    mute: Service.isConnected() && !Service.isListenOnly(),
+    unmute: Service.isConnected() && !Service.isListenOnly() && Service.isMuted(),
+    join: Service.isConnected(),
+
+    handleToggleMuteMicrophone: () => Service.toggleMuteMicrophone(),
+    handleJoinAudio: () => console.log('handleJoinAudio'),
+    handleLeaveAudio: () => console.log('handleLeaveAudio'),
+  };
+}, AudioControlsContainer);
+
+// AudioControlsContainer.propTypes = propTypes;
+// AudioControlsContainer.defaultProps = defaultProps;
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/styles.scss b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/styles.scss
new file mode 100644
index 0000000000000000000000000000000000000000..dd9268be76be8e1fc4c16c4183ea6df600544bdf
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/styles.scss
@@ -0,0 +1,12 @@
+.container {
+  display: flex;
+  flex-flow: row;
+
+  > * {
+    margin: 0 1rem;
+  }
+
+  > :last-child {
+    margin-right: 0;
+  }
+}
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-menu/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-menu/component.jsx
index 71d7814aa36a4344b87431c2b3aa79c3205e9fcd..04bdb816c8c928bca84a16b8a7003351839a39d6 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-menu/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-menu/component.jsx
@@ -22,32 +22,29 @@ class JoinAudioOptions extends React.Component {
       intl,
       isInAudio,
       isInListenOnly,
+      isConnecting,
       handleJoinAudio,
       handleCloseAudio,
     } = this.props;
 
+    let onClick = handleJoinAudio;
+    let label = intl.formatMessage(intlMessages.joinAudio);
+    let color = 'primary';
+    let icon = 'audio_on';
+
     if (isInAudio || isInListenOnly) {
-      if (AudioManager.currentState == AudioManager.callStates.inConference ||
-      AudioManager.currentState == AudioManager.callStates.inListenOnly) {
-        return (
-          <Button
-            onClick={handleCloseAudio}
-            label={intl.formatMessage(intlMessages.leaveAudio)}
-            color={'danger'}
-            icon={'audio_off'}
-            size={'lg'}
-            circle
-          />
-        );
-      }
+      onClick = handleCloseAudio;
+      label = intl.formatMessage(intlMessages.leaveAudio);
+      color = 'danger';
+      icon = 'audio_off';
     }
 
     return (
       <Button
-        onClick={handleJoinAudio}
-        label={intl.formatMessage(intlMessages.joinAudio)}
-        color={'primary'}
-        icon={'audio_on'}
+        onClick={onClick}
+        label={label}
+        color={color}
+        icon={icon}
         size={'lg'}
         circle
       />
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-menu/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-menu/container.jsx
index fad6b8d9ef230091c866cb5531673e12c5ac4a28..f838b868bad7291a6fc304a95c4e217f11663195 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-menu/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-menu/container.jsx
@@ -1,20 +1,18 @@
 import React from 'react';
 import { createContainer } from 'meteor/react-meteor-data';
-import VoiceUsers from '/imports/api/2.0/voice-users';
-import Auth from '/imports/ui/services/auth/index';
 import JoinAudioOptions from './component';
+import AudioManager from '/imports/ui/services/audio-manager';
 
 const JoinAudioOptionsContainer = props => (<JoinAudioOptions {...props} />);
 
 export default createContainer((params) => {
-  const userId = Auth.userID;
-  const voiceUser = VoiceUsers.findOne({ intId: userId });
-
-  const { joined, listenOnly } = voiceUser;
+  console.log(AudioManager);
+  const { connected, isListenOnly, connecting } = AudioManager;
 
   return {
-    isInAudio: joined,
-    isInListenOnly: listenOnly,
+    isInAudio: connected,
+    isConnecting: connecting,
+    isInListenOnly: isListenOnly,
     handleJoinAudio: params.handleJoinAudio,
     handleCloseAudio: params.handleCloseAudio,
   };
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx
index 089a247f3b0ffc79c6dde6010ccb4520b73452f0..3c76e00120a3311d1b6a387e9dce536b9b774fd0 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx
@@ -107,7 +107,7 @@ class AudioSettings extends React.Component {
             <div className={styles.col}>
               <div className={styles.formElement}>
                 <label className={cx(styles.label, styles.labelSmall)}>
-                  {intl.formatMessage(intlMessages.streamVolumeLabel)}               
+                  {intl.formatMessage(intlMessages.streamVolumeLabel)}
                   <AudioStreamVolume
                     deviceId={this.state.inputDeviceId}
                     className={styles.audioMeter}
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-stream-volume/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-stream-volume/component.jsx
index 0104cd50d5618886324c9ce843264d87cdc924b6..bd733931234d8e093e8b8c6e284b927674581a02 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-stream-volume/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-stream-volume/component.jsx
@@ -89,7 +89,7 @@ class AudioStreamVolume extends Component {
   handleConnectStreamToProcessor(stream) {
     this.source = this.audioContext.createMediaStreamSource(stream);
     this.source.connect(this.scriptProcessor);
-    this.scriptProcessor.connect(this.audioContext.destination);
+    // this.scriptProcessor.connect(this.audioContext.destination);
   }
 
   handleAudioProcess(event) {
diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/mute-button/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/mute-button/component.jsx
similarity index 66%
rename from bigbluebutton-html5/imports/ui/components/actions-bar/mute-button/component.jsx
rename to bigbluebutton-html5/imports/ui/components/audio/mute-button/component.jsx
index be0d7190f7d1de9a95b905800689327ed1e94f4c..b20650d198bc3c411ed536d9bca9e2b4ec6bf852 100755
--- a/bigbluebutton-html5/imports/ui/components/actions-bar/mute-button/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/mute-button/component.jsx
@@ -1,7 +1,7 @@
 import React from 'react';
 import Button from '/imports/ui/components/button/component';
-import styles from '../styles.scss';
-
+import styles from './styles.scss';
+//
 import { defineMessages, injectIntl } from 'react-intl';
 
 const intlMessages = defineMessages({
@@ -21,35 +21,34 @@ class MuteAudio extends React.Component {
     const {
       isInAudio,
       isMuted,
-      callback,
+      toggleMuteMicrophone,
       isTalking,
       intl,
+      isListenOnly,
     } = this.props;
 
-    if (!isInAudio) return null;
-    const muteLabel = intl.formatMessage(intlMessages.muteLabel);
-    const unmuteLabel = intl.formatMessage(intlMessages.unmuteLabel);
-
-    const label = !isMuted ? muteLabel : unmuteLabel;
     const icon = !isMuted ? 'unmute' : 'mute';
-    const tabIndex = !isInAudio ? -1 : 0;
-    let className = null;
+    const label = intl.formatMessage(!isMuted ? intlMessages.muteLabel :
+                                                intlMessages.unmuteLabel);
+    // const tabIndex = !isInAudio ? -1 : 0;
+    let className;
 
-    if (isInAudio && isTalking) {
+    if (isTalking) {
       className = styles.circleGlow;
     }
 
     return (
       <Button
-        onClick={callback}
+        onClick={toggleMuteMicrophone}
         label={label}
         color={'primary'}
         icon={icon}
         size={'lg'}
         circle
         className={className}
-        tabIndex={tabIndex}
       />
+
+        //tabIndex={tabIndex}
     );
   }
 }
diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/mute-button/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/mute-button/container.jsx
similarity index 59%
rename from bigbluebutton-html5/imports/ui/components/actions-bar/mute-button/container.jsx
rename to bigbluebutton-html5/imports/ui/components/audio/mute-button/container.jsx
index 175aebd3f4a3e57b9459c2de8d2389e80cfd7ed0..c74a7895b920d55051ac13a54b249f89c568f2ef 100755
--- a/bigbluebutton-html5/imports/ui/components/actions-bar/mute-button/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/mute-button/container.jsx
@@ -1,9 +1,9 @@
 import React from 'react';
 import { createContainer } from 'meteor/react-meteor-data';
-import { makeCall } from '/imports/ui/services/api';
 import VoiceUsers from '/imports/api/2.0/voice-users';
 import Auth from '/imports/ui/services/auth/index';
 import MuteAudio from './component';
+import AudioManager from '/imports/ui/services/audio-manager';
 
 const MuteAudioContainer = props => (<MuteAudio {...props} />);
 
@@ -11,14 +11,15 @@ export default createContainer(() => {
   const userId = Auth.userID;
   const voiceUser = VoiceUsers.findOne({ intId: userId });
 
-  const { muted, joined, talking } = voiceUser;
+  const { isConnected, isMuted, toggleMuteMicrophone } = AudioManager;
+  const { talking } = voiceUser;
 
-  const callback = () => makeCall('toggleSelfVoice');
+  // const callback = () => makeCall('toggleSelfVoice');
 
   const data = {
-    isInAudio: joined,
-    isMuted: muted,
-    callback,
+    isConnected: isConnected,
+    isMuted: isMuted,
+    toggleMuteMicrophone: toggleMuteMicrophone.bind(AudioManager),
     isTalking: talking,
   };
   return data;
diff --git a/bigbluebutton-html5/imports/ui/components/audio/mute-button/styles.scss b/bigbluebutton-html5/imports/ui/components/audio/mute-button/styles.scss
new file mode 100644
index 0000000000000000000000000000000000000000..1c4da32635f042c0fa3eeb5779108c5e6eb7289d
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/components/audio/mute-button/styles.scss
@@ -0,0 +1,3 @@
+.circleGlow > :first-child{
+    box-shadow: 0 0 .15rem #FFF !important;
+}
diff --git a/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/component.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..7ed959b2c5c72a89cf874704465149efb099139a
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/component.jsx
@@ -0,0 +1,16 @@
+import React, { Component } from 'react';
+import Button from '/imports/ui/components/button/component';
+import styles from './styles.scss';
+//
+import { defineMessages, injectIntl } from 'react-intl';
+
+class OpenAudioModalButton extends Component {
+
+  render() {
+    return (
+      <h1>asdasdasasdsad</h1>
+    );
+  }
+}
+
+export default injectIntl(OpenAudioModalButton);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/container.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..c74a7895b920d55051ac13a54b249f89c568f2ef
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/container.jsx
@@ -0,0 +1,26 @@
+import React from 'react';
+import { createContainer } from 'meteor/react-meteor-data';
+import VoiceUsers from '/imports/api/2.0/voice-users';
+import Auth from '/imports/ui/services/auth/index';
+import MuteAudio from './component';
+import AudioManager from '/imports/ui/services/audio-manager';
+
+const MuteAudioContainer = props => (<MuteAudio {...props} />);
+
+export default createContainer(() => {
+  const userId = Auth.userID;
+  const voiceUser = VoiceUsers.findOne({ intId: userId });
+
+  const { isConnected, isMuted, toggleMuteMicrophone } = AudioManager;
+  const { talking } = voiceUser;
+
+  // const callback = () => makeCall('toggleSelfVoice');
+
+  const data = {
+    isConnected: isConnected,
+    isMuted: isMuted,
+    toggleMuteMicrophone: toggleMuteMicrophone.bind(AudioManager),
+    isTalking: talking,
+  };
+  return data;
+}, MuteAudioContainer);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/styles.scss b/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/styles.scss
new file mode 100644
index 0000000000000000000000000000000000000000..1c4da32635f042c0fa3eeb5779108c5e6eb7289d
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/styles.scss
@@ -0,0 +1,3 @@
+.circleGlow > :first-child{
+    box-shadow: 0 0 .15rem #FFF !important;
+}
diff --git a/bigbluebutton-html5/imports/ui/components/audio/service.js b/bigbluebutton-html5/imports/ui/components/audio/service.js
index 4238d4eac9350ff39243d092f54d3070aa0510a9..65a2fcada3f1058f056a747c1579126c86b95536 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/service.js
+++ b/bigbluebutton-html5/imports/ui/components/audio/service.js
@@ -1,9 +1,10 @@
 import Users from '/imports/api/2.0/users';
 import Auth from '/imports/ui/services/auth';
-import AudioManager from '/imports/api/2.0/audio/client/manager';
+import AudioManager from '/imports/ui/services/audio-manager';
 import Meetings from '/imports/api/2.0/meetings';
 
 const init = () => {
+  console.log('Running audio service init.');
   const userId = Auth.userID;
   const User = Users.findOne({ userId });
   const username = User.name;
@@ -20,16 +21,19 @@ const init = () => {
     microphoneLockEnforced,
   };
 
-  AudioManager.init(userData);
+  AudioManager.userData = userData;
 };
 
-const exitAudio = () => AudioManager.exitAudio();
-const joinListenOnly = () => AudioManager.joinAudio(true);
-const joinMicrophone = () => AudioManager.joinAudio(false);
-
 export default {
   init,
-  exitAudio,
-  joinListenOnly,
-  joinMicrophone,
+  exitAudio: () => AudioManager.exitAudio(),
+  joinListenOnly: () => AudioManager.joinAudio(true),
+  joinMicrophone: () => AudioManager.joinAudio(),
+  toggleMuteMicrophone: () => AudioManager.toggleMuteMicrophone(),
+  isConnected: () => AudioManager.isConnected,
+  isMuted: () => AudioManager.isMuted,
+  isConnecting: () => AudioManager.isConnecting,
+  isListenOnly: () => AudioManager.isListenOnly,
+  inputDeviceId: () => AudioManager.inputDeviceId,
+  outputDeviceId: () => AudioManager.outputDeviceId,
 };
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js
index 071ccd55467e0d85509aaf9b777d4b4e131285e1..2a7eb629744596f207aa7a3eba509e27cf68a93f 100644
--- a/bigbluebutton-html5/imports/ui/components/user-list/service.js
+++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js
@@ -141,6 +141,9 @@ const userFindSorting = {
 };
 
 const getUsers = () => {
+  console.log('REMOVE ME BEFORE COMMIT');
+  window.Users = Users;
+
   const users = Users
     .find({ connectionStatus: 'online' }, userFindSorting)
     .fetch();
diff --git a/bigbluebutton-html5/imports/ui/services/audio-manager/index.js b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..69eeb03288099eb1180f21d13994fc49d30ccd33
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
@@ -0,0 +1,110 @@
+import { Tracker } from 'meteor/tracker';
+
+const joinAudioMicrophone = (cb) => {
+  this.setTimeout(() => {
+    console.log('joining microphone mock...');
+    cb();
+  }, 1000)
+}
+
+const exitAudio = (cb) => {
+  setTimeout(() => {
+    console.log('exit audio mock...');
+    cb();
+  }, 1000);
+}
+
+const toggleMuteMicrophone = (cb) => {
+  cb();
+}
+
+// const collection = new Mongo.Collection(null);
+
+class AudioManager {
+  constructor() {
+    this.defineProperties({
+      isMuted: false,
+      isConnected: false,
+      isConnecting: false,
+      isListenOnly: null,
+      error: null,
+      inputDeviceId: null,
+      outputDeviceId: null,
+    });
+  }
+
+  defineProperties(obj) {
+    Object.keys(obj).forEach(key => {
+      let originalKey = `_${key}`;
+      this[originalKey] = {
+        value: obj[key],
+        tracker: new Tracker.Dependency
+      }
+
+      Object.defineProperty(this, key, {
+        set: (value) => {
+          this[originalKey].value = value;
+          this[originalKey].tracker.changed();
+          // console.log('set', originalKey, value);
+          // this.update(originalKey, value);
+        },
+        get: () => {
+          this[originalKey].tracker.depend();
+          return this[originalKey].value;
+          // console.log('get', originalKey, collection.findOne({})[originalKey]);
+          // return collection.findOne({})[originalKey];
+        }
+      })
+    })
+
+    // return collection.insert(obj);
+  }
+
+  joinAudio(isListenOnly) {
+    console.log('joinAudio', this, isListenOnly);
+    this.isConnecting = true;
+    this.isListenOnly = isListenOnly
+
+    joinAudioMicrophone(this.onAudioJoin.bind(this));
+  }
+
+  exitAudio() {
+    console.log('exitAudio', this);
+    exitAudio(this.onAudioExit.bind(this));
+  }
+
+  toggleMuteMicrophone() {
+    console.log('toggleMuteMicrophone', this);
+    toggleMuteMicrophone(this.onToggleMicrophoneMute.bind(this));
+  }
+
+  //----------------------------
+
+  onAudioJoin() {
+    this.isConnected = true;
+    this.isConnecting = false;
+    console.log('onAudioJoin', this);
+  }
+
+  onAudioExit() {
+    this.isConnected = false;
+    this.isListenOnly = null;
+    this.isMuted = false;
+    console.log('onAudioExit', this);
+  }
+
+  onToggleMicrophoneMute() {
+    this.isMuted = !this.isMuted;
+    console.log('onToggleMicrophoneMute', this);
+  }
+
+  //---------------------------
+  // update(key, value) {
+  //   const query = { _id: this.stateId };
+  //   const modifier = { $set: { [key]: value }};
+  //   collection.update(query, modifier);
+  // }
+}
+
+const audioManager = new AudioManager();
+export default audioManager;