JSFiddle - React, Tailwind, and code Playground

JavaScript

var test = {
    _currentMicrophoneLabel: function () {
      var ret;

      if (test._microphone) {
        var tracks = test._microphone.getTracks();
        var track = tracks.length === 1 ? tracks[0] : undefined;
        ret = track ? track.label : undefined;
      }

      return ret;
    },
    
    _reconnectMicrophone: function () {
      test._disconnectMicrophone();

      return test._connectMicrophone()
        .catch(function () {
          test._disconnectMicrophone();
        });
    },

    _disconnectMicrophone: function () {
      console.info('disconnect microphone');

      if (test._microphone) {
        test._microphone.oninactive = null;

        test._microphone.getTracks().forEach(function (track) {
          track.stop();
        });

        delete test._microphone;
        delete test._microphoneSource;
      }
    },

    _connectMicrophone: function () {
      console.info('connect microphone');

      var ret = window.Promise.resolve();

      if (!test.isMicrophoneAvailable()) {
        ret = window.navigator.mediaDevices.getUserMedia({ audio: { deviceId: 'default' }, video: false })
          .then(function (microphone) {
            test._microphone = microphone;

            console.info('got microphone:', test._currentMicrophoneLabel());

            test._microphoneSource = test._audioContext.createMediaStreamSource(test._microphone);
						test._trackActiveMicrophone();
          })
          .catch(function (error) {
            console.warn('cannot connect microphone, error: ' + error);
            throw error;
          });
      }

      return ret;
    },
    
    _trackActiveMicrophone: function () {
      test._microphone.oninactive = function (event) {
        if (event.target === test._microphone) {
          console.info('microphone was lost');

          test._reconnectMicrophone();
        }
      };
    },
    
    _trackMediaDevices: function () {
      console.info('track media devices');

     ...