webrtc音频设备断开连接并重新连接

时间:2019-03-01 02:17:35

标签: javascript audio webrtc

我有一个基于WebRTC的视频通话应用程序。它按预期工作。但是,在通话进行时,如果我断开连接并重新连接音频设备(麦克风+扬声器),则只有扬声器部分正在工作。麦克风部分似乎无法正常工作-对方听不见了。

一旦音频设备重新连接后,是否可以通知WebRTC重新进行音频输入?

1 个答案:

答案 0 :(得分:2)

  

一旦音频设备重新连接后,是否可以通知WebRTC重新进行音频输入?

您的问题看起来很简单-与扬声器的对称性很诱人-但是一旦我们与拥有多个摄像头和麦克风的用户打交道,事情就不那么简单了:如果您的用户断开了他们所使用的蓝牙耳机的连接,您是否应该等待他们重新连接,还是立即切换到笔记本电脑麦克风?如果是后者,如果他们稍后重新连接,您是否会切换回去?这些是应用程序决策。

处理这些事情的API主要是:endeddevicechange事件,以及replaceTrack()方法。您可能还需要deviceId约束和enumerateDevices()方法来处理多个设备。

但是,为了简单起见,让我们以问题的假设为准,以探索API:

当用户在通话中拔出唯一的麦克风(而不是照相机)时,我们的工作是在重新插入麦克风时恢复与之的对话,而不会丢失视频:

  1. 首先,我们收听ended事件,以了解本地音轨何时下降。
  2. 发生这种情况时,我们会监听devicechange事件以检测是否重新插入。
  3. 发生这种情况时,我们可以使用 enumerateDevices()检查更改的内容,或者再次尝试 getUserMedia (这次仅使用麦克风)。
  4. 如果成功,请使用await sender.replaceTrack(newAudioTrack)发送我们的新音频。

这可能看起来像这样:

let sender;

(async () => {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
    pc.addTrack(stream.getVideoTracks()[0], stream);
    sender = pc.addTrack(stream.getAudioTracks()[0], stream);
    sender.track.onended = () => navigator.mediaDevices.ondevicechange = tryAgain;
  } catch (e) {
    console.log(e);
  }
})();

async function tryAgain() {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({audio: true});
    await sender.replaceTrack(stream.getAudioTracks()[0]);
    navigator.mediaDevices.ondevicechange = null;
    sender.track.onended = () => navigator.mediaDevices.ondevicechange = tryAgain;
  } catch (e) {
    if (e.name == "NotFoundError") return;
    console.log(e);
  }
}

// Your usual WebRTC negotiation code goes here

以上内容仅供参考。我敢肯定,有很多极端的情况要考虑。