diff --git a/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js b/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js
index 8b2b07528f9cd4affe0b763aa4a79bd3cd04174c..00b959ca451ebaedb10080d93f361cfa3d363bff 100755
--- a/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js
+++ b/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js
@@ -664,6 +664,21 @@ export default class SIPBridge extends BaseAudioBridge {
     return navigator.mediaDevices.getUserMedia(constraints).then(handleMediaSuccess);
   }
 
+  liveChangeInputDevice(deviceId) {
+    const constraints = {
+      audio: {
+        deviceId,
+      },
+    };
+
+    return navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
+      const peer = this.getPeerConnection();
+      const senders = peer.getSenders()[0];
+      const firstTrack = stream.getAudioTracks()[0];
+      senders.replaceTrack(firstTrack);
+    });
+  }
+
   async changeOutputDevice(value) {
     const audioContext = document.querySelector(MEDIA_TAG);
 
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 90be874a036a3eaa2f7fb12e644011cdce02e624..f63ff9c4e7ed43ab2293c43d11cda58c58e012b1 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx
@@ -5,6 +5,7 @@ import { defineMessages, intlShape, injectIntl } from 'react-intl';
 import Button from '/imports/ui/components/button/component';
 import getFromUserSettings from '/imports/ui/services/users-settings';
 import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
+import InputStreamLiveSelectorContainer from './input-stream-live-selector/container';
 import { styles } from './styles';
 
 const intlMessages = defineMessages({
@@ -41,6 +42,11 @@ const propTypes = {
 };
 
 class AudioControls extends PureComponent {
+  constructor(props) {
+    super(props);
+    this.renderLeaveButton = this.renderLeaveButton.bind(this);
+  }
+
   componentDidMount() {
     const { processToggleMuteFromOutside } = this.props;
     if (Meteor.settings.public.allowOutsideCommands.toggleSelfVoice
@@ -49,31 +55,46 @@ class AudioControls extends PureComponent {
     }
   }
 
+  renderLeaveButton() {
+    const {
+      listenOnly,
+      inAudio,
+      isVoiceUser,
+      handleLeaveAudio,
+      shortcuts,
+      disable,
+      intl,
+    } = this.props;
+    return (inAudio && isVoiceUser && listenOnly) ? (
+      <Button
+        onClick={handleLeaveAudio}
+        disabled={disable}
+        hideLabel
+        aria-label={intl.formatMessage(intlMessages.leaveAudio)}
+        label={intl.formatMessage(intlMessages.leaveAudio)}
+        color="primary"
+        icon="listen"
+        size="lg"
+        circle
+        accessKey={shortcuts.leaveAudio}
+      />
+    ) : (<InputStreamLiveSelectorContainer />);
+  }
+
   render() {
     const {
       handleToggleMuteMicrophone,
       handleJoinAudio,
-      handleLeaveAudio,
       showMute,
       muted,
       disable,
       talking,
       inAudio,
-      listenOnly,
       intl,
       shortcuts,
       isVoiceUser,
     } = this.props;
 
-    let joinIcon = 'audio_off';
-    if (inAudio) {
-      if (listenOnly) {
-        joinIcon = 'listen';
-      } else {
-        joinIcon = 'audio_on';
-      }
-    }
-
     return (
       <span className={styles.container}>
         {showMute && isVoiceUser
@@ -92,25 +113,29 @@ class AudioControls extends PureComponent {
               icon={muted ? 'mute' : 'unmute'}
               size="lg"
               circle
-              accessKey={shortcuts.toggleMute}
+              // accessKey={shortcuts.toggleMute}
             />
           ) : null}
-        <Button
-          className={cx(styles.button, inAudio || styles.btn)}
-          onClick={inAudio ? handleLeaveAudio : handleJoinAudio}
-          disabled={disable}
-          hideLabel
-          aria-label={inAudio ? intl.formatMessage(intlMessages.leaveAudio)
-            : intl.formatMessage(intlMessages.joinAudio)}
-          label={inAudio ? intl.formatMessage(intlMessages.leaveAudio)
-            : intl.formatMessage(intlMessages.joinAudio)}
-          color={inAudio ? 'primary' : 'default'}
-          ghost={!inAudio}
-          icon={joinIcon}
-          size="lg"
-          circle
-          accessKey={inAudio ? shortcuts.leaveAudio : shortcuts.joinAudio}
-        />
+        {
+          (inAudio)
+            ? this.renderLeaveButton()
+            : (
+              <Button
+                className={cx(styles.button, styles.btn)}
+                onClick={handleJoinAudio}
+                disabled={disable}
+                hideLabel
+                aria-label={intl.formatMessage(intlMessages.joinAudio)}
+                label={intl.formatMessage(intlMessages.joinAudio)}
+                color="default"
+                ghost
+                icon={'audio_off'}
+                size="lg"
+                circle
+                accessKey={shortcuts.joinAudio}
+              />
+            )
+        }
       </span>);
   }
 }
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/input-stream-live-selector/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/input-stream-live-selector/component.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..950d70384cdd5df095c5789d3fe17a5af5dec940
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/input-stream-live-selector/component.jsx
@@ -0,0 +1,158 @@
+import React, { Component, Fragment } from 'react';
+import { defineMessages, injectIntl } from 'react-intl';
+import PropTypes from 'prop-types';
+import Button from '/imports/ui/components/button/component';
+import Dropdown from '/imports/ui/components/dropdown/component';
+import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component';
+import DropdownContent from '/imports/ui/components/dropdown/content/component';
+import DropdownList from '/imports/ui/components/dropdown/list/component';
+import DropdownListSeparator from '/imports/ui/components/dropdown/list/separator/component';
+import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
+import DropdownListTitle from '/imports/ui/components/dropdown/list/title/component';
+import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
+
+import { styles } from '../styles';
+
+const AUDIO_INPUT = 'audioinput';
+const AUDIO_OUTPUT = 'audiooutput';
+
+const intlMessages = defineMessages({
+  changeLeaveAudio: {
+    id: 'app.audio.changeLeaveAudio',
+    description: 'Change/Leave audio button label',
+  },
+  leaveAudio: {
+    id: 'app.audio.leaveAudio',
+    description: 'Leave audio dropdown item label',
+  },
+  loading: {
+    id: 'app.audio.loading',
+    description: 'Loading audio dropdown item label',
+  },
+  input: {
+    id: 'app.audio.input',
+    description: 'Input audio dropdown item label',
+  },
+  output: {
+    id: 'app.audio.output',
+    description: 'Output audio dropdown item label',
+  },
+});
+
+const propTypes = {
+  liveChangeInputDevice: PropTypes.func.isRequired,
+  exitAudio: PropTypes.func.isRequired,
+  liveChangeOutputDevice: PropTypes.func.isRequired,
+  intl: PropTypes.object.isRequired,
+  shortcuts: PropTypes.object.isRequired,
+};
+
+class InputStreamLiveSelector extends Component {
+  constructor(props) {
+    super(props);
+    this.setInputDevices = this.setInputDevices.bind(this);
+    this.setOutputDevices = this.setOutputDevices.bind(this);
+    this.renderDeviceList = this.renderDeviceList.bind(this);
+    this.state = {
+      audioInputDevices: null,
+      audioOutputDevices: null,
+    };
+  }
+
+  componentDidMount() {
+    this.setInputDevices();
+    this.setOutputDevices();
+  }
+
+  setInputDevices() {
+    navigator.mediaDevices.enumerateDevices()
+      .then((devices) => {
+        this.setState({
+          audioInputDevices: devices.filter(i => i.kind === AUDIO_INPUT),
+        });
+      });
+  }
+
+  setOutputDevices() {
+    navigator.mediaDevices.enumerateDevices()
+      .then((devices) => {
+        this.setState({
+          audioOutputDevices: devices.filter(i => i.kind === AUDIO_OUTPUT),
+        });
+      });
+  }
+
+  renderDeviceList(list, callback, title) {
+    const { intl } = this.props;
+    return [
+      <DropdownListTitle>{title}</DropdownListTitle>,
+      list ? list.map(device => (
+        <DropdownListItem
+          key={device.deviceId}
+          label={device.label}
+          onClick={() => callback(device.deviceId)}
+        />
+      ))
+        : (
+          <DropdownListItem
+            label={intl.formatMessage(intlMessages.loading)}
+          />
+        ),
+      <DropdownListSeparator />,
+    ];
+  }
+
+  render() {
+    const { audioInputDevices, audioOutputDevices } = this.state;
+    const {
+      liveChangeInputDevice,
+      exitAudio,
+      liveChangeOutputDevice,
+      intl,
+      shortcuts,
+    } = this.props;
+    return (
+      <Dropdown>
+        <DropdownTrigger>
+          <Button
+            aria-label={intl.formatMessage(intlMessages.changeLeaveAudio)}
+            label={intl.formatMessage(intlMessages.changeLeaveAudio)}
+            hideLabel
+            color="primary"
+            icon="audio_on"
+            size="lg"
+            circle
+            onClick={()=>{
+              this.setInputDevices();
+              this.setOutputDevices();
+            }}
+            accessKey={shortcuts.leaveAudio}
+          />
+        </DropdownTrigger>
+        <DropdownContent>
+          <DropdownList className={styles.dropdownListContainer}>
+            {this.renderDeviceList(
+              audioInputDevices,
+              liveChangeInputDevice,
+              intl.formatMessage(intlMessages.input),
+            )}
+            {this.renderDeviceList(
+              audioOutputDevices,
+              liveChangeOutputDevice,
+              intl.formatMessage(intlMessages.output)
+            )}
+            <DropdownListItem
+              className={styles.stopButton}
+              label={intl.formatMessage(intlMessages.leaveAudio)}
+              onClick={() => exitAudio()}
+            />
+          </DropdownList>
+        </DropdownContent>
+      </Dropdown>
+    );
+  }
+}
+
+InputStreamLiveSelector.propTypes = propTypes;
+
+export default withShortcutHelper(injectIntl(InputStreamLiveSelector));
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/input-stream-live-selector/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/input-stream-live-selector/container.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..25d30c32ee8c2195bccbd9c90843a089d1124a19
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/input-stream-live-selector/container.jsx
@@ -0,0 +1,20 @@
+import React, { PureComponent } from 'react';
+import { withTracker } from 'meteor/react-meteor-data';
+import InputStreamLiveSelector from './component';
+import Service from '../../service';
+
+class InputStreamLiveSelectorContainer extends PureComponent {
+  render() {
+    return (
+      <InputStreamLiveSelector {...this.props} />
+    );
+  }
+}
+
+export default withTracker(() => {
+  return {
+    liveChangeInputDevice: Service.liveChangeInputDevice,
+    liveChangeOutputDevice: Service.changeOutputDevice,
+    exitAudio: Service.exitAudio,
+  };
+})(InputStreamLiveSelectorContainer);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/styles.scss b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/styles.scss
index 702f765146bfd25adb75f2b88c60bb9a0c21877a..2f710c5aabb080ed89baf4443d3b47fc7d7a96d0 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/styles.scss
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/styles.scss
@@ -59,4 +59,14 @@
   100% {
     box-shadow: 0 0 0 0 transparent;
   }
+}
+
+.dropdownListContainer {
+  min-width: 10rem;
+}
+
+.stopButton {
+  & > span {
+    color: var(--color-danger);
+  }
 }
\ No newline at end of file
diff --git a/bigbluebutton-html5/imports/ui/components/audio/service.js b/bigbluebutton-html5/imports/ui/components/audio/service.js
index 0e7ffaf27c29391c97fb420a61722c70a7fc7c81..e6446e5453affc196848f2a276a0b70147a0867f 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/service.js
+++ b/bigbluebutton-html5/imports/ui/components/audio/service.js
@@ -70,6 +70,7 @@ export default {
   joinEchoTest: () => AudioManager.joinEchoTest(),
   toggleMuteMicrophone: debounce(toggleMuteMicrophone, 500, { leading: true, trailing: false }),
   changeInputDevice: inputDeviceId => AudioManager.changeInputDevice(inputDeviceId),
+  liveChangeInputDevice: inputDeviceId => AudioManager.liveChangeInputDevice(inputDeviceId),
   changeOutputDevice: outputDeviceId => AudioManager.changeOutputDevice(outputDeviceId),
   isConnected: () => AudioManager.isConnected,
   isTalking: () => AudioManager.isTalking,
diff --git a/bigbluebutton-html5/imports/ui/services/audio-manager/index.js b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
index 4b7f36cad3df23ddc044cd9f22e8dc8962bdf088..092c5c91fa638a28ae43b6fc40278f77355c1482 100755
--- a/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
+++ b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
@@ -476,6 +476,14 @@ class AudioManager {
       .catch(handleChangeInputDeviceError);
   }
 
+  liveChangeInputDevice(deviceId) {
+    const handleChangeInputDeviceSuccess = (inputDevice) => {
+      this.inputDevice = inputDevice;
+      return Promise.resolve(inputDevice);
+    };
+    this.bridge.liveChangeInputDevice(deviceId).then(handleChangeInputDeviceSuccess);
+  }
+
   async changeOutputDevice(deviceId) {
     this.outputDeviceId = await this.bridge.changeOutputDevice(deviceId);
   }
diff --git a/bigbluebutton-html5/private/locales/en.json b/bigbluebutton-html5/private/locales/en.json
index 5ac23b4386e3f924bdbea7424b61bac80402b97c..5e49653ce15a267ca1a15e18ff52631c0ee931ac 100755
--- a/bigbluebutton-html5/private/locales/en.json
+++ b/bigbluebutton-html5/private/locales/en.json
@@ -429,9 +429,13 @@
     "app.audioManager.mediaError": "Error: There was an issue getting your media devices",
     "app.audio.joinAudio": "Join audio",
     "app.audio.leaveAudio": "Leave audio",
+    "app.audio.changeLeaveAudio": "Change/Leave audio",
     "app.audio.enterSessionLabel": "Enter session",
     "app.audio.playSoundLabel": "Play sound",
     "app.audio.backLabel": "Back",
+    "app.audio.loading": "Loading",
+    "app.audio.input": "Input",
+    "app.audio.output": "Output",
     "app.audio.audioSettings.titleLabel": "Choose your audio settings",
     "app.audio.audioSettings.descriptionLabel": "Please note, a dialog will appear in your browser, requiring you to accept sharing your microphone.",
     "app.audio.audioSettings.microphoneSourceLabel": "Microphone source",