diff --git a/bigbluebutton-html5/imports/api/phone/index.js b/bigbluebutton-html5/imports/api/phone/index.js
deleted file mode 100755
index 05101454fb0894b0425e385d99b4d2c7c9dbe8ae..0000000000000000000000000000000000000000
--- a/bigbluebutton-html5/imports/api/phone/index.js
+++ /dev/null
@@ -1,151 +0,0 @@
-// TODO: This file should be a `service.js` somewhere in the /ui folder
-import Users from '/imports/api/users';
-import Meetings from '/imports/api/meetings';
-import Auth from '/imports/ui/services/auth';
-import {callServer} from '/imports/ui/services/api';
-import {vertoExitAudio, vertoJoinListenOnly, vertoJoinMicrophone} from '/imports/api/verto';
-
-const APP_CONFIG = Meteor.settings.public.app;
-const MEDIA_CONFIG = Meteor.settings.public.media;
-
-let triedHangup = false;
-
-function getVoiceBridge() {
-  return Meetings.findOne({}).voiceConf;
-}
-
-function amIListenOnly() {
-  const uid = Auth.userID;
-  return Users.findOne({ userId: uid }).user.listenOnly;
-}
-
-// Periodically check the status of the WebRTC call, when a call has been established attempt to
-// hangup, retry if a call is in progress, send the leave voice conference message to BBB
-
-function exitAudio(afterExitCall = () => {}) {
-  if (!MEDIA_CONFIG.useSIPAudio) {
-    vertoExitAudio();
-    return;
-  } else {
-    // To be called when the hangup is initiated
-    const hangupCallback = function () {
-      console.log('Exiting Voice Conference');
-    };
-
-    // Checks periodically until a call is established so we can successfully end the call
-    // clean state
-    triedHangup = false;
-
-    // function to initiate call
-    const checkToHangupCall = ((context, afterExitCall = () => {}) => {
-
-      // if an attempt to hang up the call is made when the current session is not yet finished,
-      // the request has no effect
-      // keep track in the session if we haven't tried a hangup
-      if (window.getCallStatus() != null && !triedHangup) {
-        console.log('Attempting to hangup on WebRTC call');
-
-        // notify BBB-apps we are leaving the call call if we are listen only
-        if (amIListenOnly()) {
-          callServer('listenOnlyRequestToggle', false);
-        }
-
-        window.webrtc_hangup(hangupCallback);
-
-        // we have hung up, prevent retries
-        triedHangup = true;
-
-        if (afterExitCall) {
-          afterExitCall(this, APP_CONFIG.listenOnly);
-        }
-      } else {
-        console.log('RETRYING hangup on WebRTC call in ' +
-          `${MEDIA_CONFIG.WebRTCHangupRetryInterval} ms`);
-
-        // try again periodically
-        setTimeout(checkToHangupCall, MEDIA_CONFIG.WebRTCHangupRetryInterval);
-      }
-    })
-
-    // automatically run function
-    (this, afterExitCall);
-
-    return false;
-  };
-}
-
-// join the conference. If listen only send the request to the server
-function joinVoiceCallSIP(options) {
-  const extension = getVoiceBridge();
-  console.log(options);
-  if (MEDIA_CONFIG.useSIPAudio) {
-
-    // create voice call params
-    const joinCallback = function (message) {
-      console.log('Beginning WebRTC Conference Call');
-    };
-
-    window.BBB = {};
-    window.BBB.getMyUserInfo = function (callback) {
-      const uid = Auth.userID;
-      const result = {
-        myUserID: uid,
-        myUsername: Users.findOne({ userId: uid }).user.name,
-        myInternalUserID: uid,
-        myAvatarURL: null,
-        myRole: 'getMyRole',
-        amIPresenter: 'false',
-        voiceBridge: extension,
-        dialNumber: null,
-      };
-      return callback(result);
-    };
-
-    const m = Meetings.findOne();
-    const st = {
-      stun: m.stuns,
-      turn: m.turns,
-    };
-
-    callIntoConference(extension, function (audio) {
-      switch (audio.status) {
-        case 'failed':
-          let audioFailed = new CustomEvent('bbb.webrtc.failed', {
-            status: 'Failed' });
-          window.dispatchEvent(audioFailed);
-          break;
-        case 'mediafail':
-          let mediaFailed = new CustomEvent('bbb.webrtc.mediaFailed', {
-            status: 'MediaFailed' });
-          window.dispatchEvent(mediaFailed);
-          break;
-        case 'mediasuccess':
-        case 'started':
-          let connected = new CustomEvent('bbb.webrtc.connected', {
-            status: 'started' });
-          window.dispatchEvent(connected);
-          break;
-      }
-    }, options.isListenOnly, st);
-    return;
-  }
-}
-
-function joinListenOnly() {
-  callServer('listenOnlyRequestToggle', true);
-  if (MEDIA_CONFIG.useSIPAudio) {
-    joinVoiceCallSIP({ isListenOnly: true });
-  } else {
-    vertoJoinListenOnly();
-  }
-}
-
-function joinMicrophone() {
-  if (MEDIA_CONFIG.useSIPAudio) {
-    joinVoiceCallSIP({ isListenOnly: false });
-  } else {
-    vertoJoinMicrophone();
-  }
-}
-
-export { joinListenOnly, joinMicrophone, exitAudio, getVoiceBridge, };
diff --git a/bigbluebutton-html5/imports/api/verto/index.js b/bigbluebutton-html5/imports/api/verto/index.js
index 99720b7eca15151bb9eaf5efc410877c5903d072..41bc595a322e223767ed082322f893b3acf98ba3 100755
--- a/bigbluebutton-html5/imports/api/verto/index.js
+++ b/bigbluebutton-html5/imports/api/verto/index.js
@@ -1,7 +1,7 @@
-import {getInStorage} from '/imports/ui/components/app/service';
+import { getInStorage } from '/imports/ui/components/app/service';
 import Users from '/imports/api/users';
 import Auth from '/imports/ui/services/auth';
-import { getVoiceBridge } from '/imports/api/phone';
+import { getVoiceBridge } from '/imports/ui/components/audio/service';
 
 function createVertoUserName() {
   const uid = Auth.userID;
diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx
index f3d529b46ee21f17e42e08637b83681ead54d126..ad92643f5359440f6682795fcfde4f6956eb2d4f 100755
--- a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
 import { createContainer } from 'meteor/react-meteor-data';
 import ActionsBar from './component';
 import Service from './service';
+import { exitAudio, handleJoinAudio } from '../audio/service';
 
 class ActionsBarContainer extends Component {
   constructor(props) {
@@ -20,8 +21,8 @@ class ActionsBarContainer extends Component {
 
 export default createContainer(() => {
   const isPresenter = Service.isUserPresenter();
-  const handleExitAudio = () => Service.handleExitAudio();
-  const handleOpenJoinAudio = () => Service.handleJoinAudio();
+  const handleExitAudio = () => exitAudio();
+  const handleOpenJoinAudio = () => handleJoinAudio();
 
   return {
     isUserPresenter: isPresenter,
diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/service.js b/bigbluebutton-html5/imports/ui/components/actions-bar/service.js
index ae6381611448dc31b94fbc93c4927e631c675b65..741adaddd5960ce4f896d260a912f5e33682d7ea 100755
--- a/bigbluebutton-html5/imports/ui/components/actions-bar/service.js
+++ b/bigbluebutton-html5/imports/ui/components/actions-bar/service.js
@@ -1,10 +1,6 @@
 import React from 'react';
 import AuthSingleton from '/imports/ui/services/auth/index.js';
 import Users from '/imports/api/users';
-import { joinListenOnly } from '/imports/api/phone';
-import { showModal } from '/imports/ui/components/app/service';
-import { exitAudio } from '/imports/api/phone';
-import Audio from '/imports/ui/components/audio/audio-modal/component';
 
 let isUserPresenter = () => {
 
@@ -18,17 +14,6 @@ let isUserPresenter = () => {
   };
 };
 
-const handleExitAudio = () => {
-  return exitAudio();
-}
-
-const handleJoinAudio = () => {
-  const handleJoinListenOnly = () => joinListenOnly();
-  return showModal(<Audio handleJoinListenOnly={handleJoinListenOnly} />);
-}
-
 export default {
   isUserPresenter,
-  handleJoinAudio,
-  handleExitAudio,
 };
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-modal/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-modal/container.jsx
index d49bd018927f640801dc08bd06139170af7a0ab2..0c01f8f2469e697c5fccc9f604dd6355b6b71800 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-modal/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-modal/container.jsx
@@ -1,7 +1,7 @@
-import React, { Component, PropTypes } from 'react';
+import React, { Component } from 'react';
 import { createContainer } from 'meteor/react-meteor-data';
 import Audio from './component';
-import { joinListenOnly } from '/imports/api/phone';
+import { joinListenOnly } from '../service';
 
 export default class AudioModalContainer extends Component {
   constructor(props) {
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 9846dc8cf449e0b0e82e0703227761bf457b824e..104d2e3b4dad90347577a3cd073c33dee6f7699a 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx
@@ -6,7 +6,7 @@ import styles from '../audio-modal/styles.scss';
 
 import DeviceSelector from '/imports/ui/components/audio/device-selector/component';
 import AudioStreamVolume from '/imports/ui/components/audio/audio-stream-volume/component';
-import EnterAudioContainer from '/imports/ui/components/enter-audio/container';
+import EnterAudioContainer from '/imports/ui/components/audio/enter-audio/container';
 import AudioTestContainer from '/imports/ui/components/audio/audio-test/container';
 import cx from 'classnames';
 
diff --git a/bigbluebutton-html5/imports/ui/components/enter-audio/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/enter-audio/component.jsx
similarity index 83%
rename from bigbluebutton-html5/imports/ui/components/enter-audio/component.jsx
rename to bigbluebutton-html5/imports/ui/components/audio/enter-audio/component.jsx
index 231007afc9e95923321a40e8e962874d52e4699d..f1dcb9a6842b0b45a7ec94b926bb4c908c14d346 100755
--- a/bigbluebutton-html5/imports/ui/components/enter-audio/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/enter-audio/component.jsx
@@ -1,7 +1,6 @@
 import React from 'react';
 import { defineMessages, injectIntl } from 'react-intl';
 import Button from '/imports/ui/components/button/component';
-import styles from '../settings/styles.scss';
 
 class EnterAudio extends React.Component {
   constructor(props) {
@@ -14,8 +13,8 @@ class EnterAudio extends React.Component {
     } = this.props;
 
     return (
-      <div className={styles.half}>
-        <Button className={styles.enterBtn}
+      <div>
+        <Button
           label={intl.formatMessage(intlMessages.enterSessionLabel)}
           size={'md'}
           color={'primary'}
diff --git a/bigbluebutton-html5/imports/ui/components/enter-audio/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/enter-audio/container.jsx
similarity index 81%
rename from bigbluebutton-html5/imports/ui/components/enter-audio/container.jsx
rename to bigbluebutton-html5/imports/ui/components/audio/enter-audio/container.jsx
index 299f254333ce1356f5ea0cccc52ab959e700bf2b..6b3dbdc3df97f2b400fd7db9b2835eb745e5a42b 100755
--- a/bigbluebutton-html5/imports/ui/components/enter-audio/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/enter-audio/container.jsx
@@ -1,6 +1,6 @@
-import React, { Component, PropTypes } from 'react';
+import React, { Component } from 'react';
 import { createContainer } from 'meteor/react-meteor-data';
-import {joinListenOnly, joinMicrophone} from '/imports/api/phone';
+import { joinListenOnly, joinMicrophone } from '../service';
 import { clearModal } from '/imports/ui/components/app/service';
 import EnterAudio from './component';
 
diff --git a/bigbluebutton-html5/imports/ui/components/audio/service.js b/bigbluebutton-html5/imports/ui/components/audio/service.js
index fa2f5d09adf7d18bae2e237c41de9c6df53c2506..e802ec2d1b77f9fdec1c87888575d85bb97179f5 100644
--- a/bigbluebutton-html5/imports/ui/components/audio/service.js
+++ b/bigbluebutton-html5/imports/ui/components/audio/service.js
@@ -1,4 +1,165 @@
 import React from 'react';
 
-export default {
+import AudioModal from './audio-modal/component';
+import Auth from '/imports/ui/services/auth';
+import Meetings from '/imports/api/meetings';
+import Users from '/imports/api/users';
+
+import { showModal } from '/imports/ui/components/app/service';
+import { callServer } from '/imports/ui/services/api';
+import { vertoExitAudio, vertoJoinListenOnly, vertoJoinMicrophone } from '/imports/api/verto';
+
+const handleJoinAudio = () => {
+  const handleJoinListenOnly = () => joinListenOnly();
+  return showModal(<AudioModal handleJoinListenOnly={handleJoinListenOnly} />);
+};
+
+const APP_CONFIG = Meteor.settings.public.app;
+const MEDIA_CONFIG = Meteor.settings.public.media;
+
+let triedHangup = false;
+
+function getVoiceBridge() {
+  return Meetings.findOne({}).voiceConf;
+}
+
+function _amIListenOnly() {
+  const uid = Auth.userID;
+  return Users.findOne({ userId: uid }).user.listenOnly;
+}
+
+// Periodically check the status of the WebRTC call, when a call has been established attempt to
+// hangup, retry if a call is in progress, send the leave voice conference message to BBB
+function exitAudio(afterExitCall = () => {}) {
+  if (!MEDIA_CONFIG.useSIPAudio) {
+    vertoExitAudio();
+    return;
+  } else {
+    // To be called when the hangup is initiated
+    const hangupCallback = function () {
+      console.log('Exiting Voice Conference');
+    };
+
+    // Checks periodically until a call is established so we can successfully end the call
+    // clean state
+    triedHangup = false;
+
+    // function to initiate call
+    const checkToHangupCall = ((context, afterExitCall = () => {}) => {
+
+      // if an attempt to hang up the call is made when the current session is not yet finished,
+      // the request has no effect
+      // keep track in the session if we haven't tried a hangup
+      if (window.getCallStatus() != null && !triedHangup) {
+        console.log('Attempting to hangup on WebRTC call');
+
+        // notify BBB-apps we are leaving the call call if we are listen only
+        if (_amIListenOnly()) {
+          callServer('listenOnlyRequestToggle', false);
+        }
+
+        window.webrtc_hangup(hangupCallback);
+
+        // we have hung up, prevent retries
+        triedHangup = true;
+
+        if (afterExitCall) {
+          afterExitCall(this, APP_CONFIG.listenOnly);
+        }
+      } else {
+        console.log('RETRYING hangup on WebRTC call in ' +
+          `${MEDIA_CONFIG.WebRTCHangupRetryInterval} ms`);
+
+        // try again periodically
+        setTimeout(checkToHangupCall, MEDIA_CONFIG.WebRTCHangupRetryInterval);
+      }
+    })
+
+    // automatically run function
+    (this, afterExitCall);
+
+    return false;
+  }
+}
+
+// join the conference. If listen only send the request to the server
+function _joinVoiceCallSIP(options) {
+  const extension = getVoiceBridge();
+  console.log(options);
+  if (MEDIA_CONFIG.useSIPAudio) {
+
+    // create voice call params
+    const joinCallback = function (message) {
+      console.log('Beginning WebRTC Conference Call');
+    };
+
+    window.BBB = {};
+    window.BBB.getMyUserInfo = function (callback) {
+      const uid = Auth.userID;
+      const result = {
+        myUserID: uid,
+        myUsername: Users.findOne({ userId: uid }).user.name,
+        myInternalUserID: uid,
+        myAvatarURL: null,
+        myRole: 'getMyRole',
+        amIPresenter: 'false',
+        voiceBridge: extension,
+        dialNumber: null,
+      };
+      return callback(result);
+    };
+
+    const m = Meetings.findOne();
+    const st = {
+      stun: m.stuns,
+      turn: m.turns,
+    };
+
+    callIntoConference(extension, function (audio) {
+      switch (audio.status) {
+        case 'failed':
+          let audioFailed = new CustomEvent('bbb.webrtc.failed', {
+            status: 'Failed' });
+          window.dispatchEvent(audioFailed);
+          break;
+        case 'mediafail':
+          let mediaFailed = new CustomEvent('bbb.webrtc.mediaFailed', {
+            status: 'MediaFailed' });
+          window.dispatchEvent(mediaFailed);
+          break;
+        case 'mediasuccess':
+        case 'started':
+          let connected = new CustomEvent('bbb.webrtc.connected', {
+            status: 'started' });
+          window.dispatchEvent(connected);
+          break;
+      }
+    }, options.isListenOnly, st);
+    return;
+  }
+}
+
+const joinListenOnly = () => {
+  callServer('listenOnlyRequestToggle', true);
+  if (MEDIA_CONFIG.useSIPAudio) {
+    _joinVoiceCallSIP({ isListenOnly: true });
+  } else {
+    vertoJoinListenOnly();
+  }
+};
+
+const joinMicrophone = () => {
+  if (MEDIA_CONFIG.useSIPAudio) {
+    _joinVoiceCallSIP({ isListenOnly: false });
+  } else {
+    vertoJoinMicrophone();
+  }
+};
+
+export {
+  handleJoinAudio,
+  getVoiceBridge,
+  exitAudio,
+  joinListenOnly,
+  joinMicrophone,
 };
diff --git a/bigbluebutton-html5/imports/ui/components/breakout-join-confirmation/component.jsx b/bigbluebutton-html5/imports/ui/components/breakout-join-confirmation/component.jsx
index e23f29fd11ea8fc5a57bde6b32b6e41c04088904..59c10cde061fb3056a9712bc93a9a602008d512b 100644
--- a/bigbluebutton-html5/imports/ui/components/breakout-join-confirmation/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/breakout-join-confirmation/component.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from 'react';
 import { defineMessages, injectIntl } from 'react-intl';
 import { clearModal } from '/imports/ui/components/app/service';
-import { exitAudio } from '/imports/api/phone'
+import { exitAudio } from '../audio/service'
 import Modal from '/imports/ui/components/modal/component';
 
 const intlMessages = defineMessages({
diff --git a/bigbluebutton-html5/imports/ui/components/deskshare/service.js b/bigbluebutton-html5/imports/ui/components/deskshare/service.js
index 99145dd25837b7492294f2547cccd215a48b5e4b..ea374ea303ed2c6a6a36300943aa2a998b169a71 100755
--- a/bigbluebutton-html5/imports/ui/components/deskshare/service.js
+++ b/bigbluebutton-html5/imports/ui/components/deskshare/service.js
@@ -1,7 +1,6 @@
 import Deskshare from '/imports/api/deskshare';
 import {createVertoUserName, watchVertoVideo} from '/imports/api/verto';
 import Auth from '/imports/ui/services/auth';
-import {getVoiceBridge} from '/imports/api/phone';
 
 // when the meeting information has been updated check to see if it was
 // desksharing. If it has changed either trigger a call to receive video