如何在连接或移除外部麦克风时更改音频输入源

How to change audio input source when external microphone is attached or removed

检测可用摄像头和麦克风的代码

function gotDevices(deviceInfos) {
  const values = selectors.map(select => select.value);
  selectors.forEach(select => {
    while (select.firstChild) {
      select.removeChild(select.firstChild);
    }
  });
  for (let i = 0; i !== deviceInfos.length; ++i) {
    const deviceInfo = deviceInfos[i];
    const option = document.createElement('option');
    option.value = deviceInfo.deviceId;
    if (deviceInfo.kind === 'audioinput') {
      option.text = deviceInfo.label || `microphone ${audioInputSelect.length + 1}`;
      audioInputSelect.appendChild(option);
      // console.log('audio source device: ', deviceInfo );
    }else if (deviceInfo.kind === 'videoinput') {
      option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`;
      videoSelect.appendChild(option);
    } else {
      // console.log('Some other kind of source/device: ', deviceInfo);
    }
  }
  selectors.forEach((select, selectorIndex) => {
    if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) {
      select.value = values[selectorIndex];
    }
  });
}

function handleError(){
        console.log("Something went wrong while fetching the input devices!!!");
}

navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError);

当音频源更改时,我更新可用设备并重新发布流,现在这里的主要问题是当我使用外部 MIC 启动流时,它正在从外部 MIC 获取音频输入,当我删除它正在从笔记本电脑的 MIC 获取音频输入,但是当我再次插入外部 MIC 时,它没有改变应该是外部 MIC 的音频输入源。

navigator.mediaDevices.ondevicechange = function(event) {
     navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError);
    republish( document.getElementById('uid').getAttribute('value') );
}

function republish(uid){
  clearAllStreams(uid);
  getMediaStream().then((stream) => {
      publishStream("camera", stream , uid);
  });
}

function clearAllStreams(uid){
    console.log(" i am clearing streams");
    let selfStream = participants[uid].stream;
    if(selfStream){
        selfStream.getTracks().forEach((track) => {
            track.stop();
        });
        console.log("all tracks stopped.");
    }
    if(publication){
        publication.stop();
        console.log("publication stopped.");
    }
}


 function getMediaStream(config = { audio: true,  video: { facingMode: "user" } }) {
    let _fetchStreamFromDevice = () => {
        return navigator.mediaDevices.getUserMedia(config);
    };

    return new Promise(async(resolve, reject) => {
        let  stream = await (_fetchStreamFromDevice()).then(stream =>{
        resolve(stream);
        }).catch(err =>{
          console.log(err);
            reject(err);
        });
    });

}

我对 getMediaStream 函数进行了以下更改,效果非常好。

  const  config = {
      audio: {  deviceId :audioDeviceId ? { exact : audioDeviceId } : undefined },
      video: {  facingMode : "user" }
    };