如何使用 OpenTok select 音频输出

How to select audioOutput with OpenTok

我正在使用 OpenTok 构建一个简单的 WebRTC 应用程序。 我需要能够 select 摄像头、音频输入和音频输出。 目前这似乎不太可能。

opentok-hardware-setup

https://github.com/opentok/opentok-hardware-setup.js/issues/18

我正在我的 index.html 文件中加载 OpenTokopentok-hardware-setup.js.

一切看起来都很棒,我可以 select 麦克风和摄像头,但不是扬声器 audiooutput

<script src="https://static.opentok.com/v2/js/opentok.min.js"></script>

我尝试从控制台

OT.getDevices((err, devices) => { console.debug(devices)});

并观察到您无法获得 audioOutput

(4) [{…}, {…}, {…}, {…}]
0: {deviceId: "default", label: "Default - Built-in Microphone", kind: "audioInput"}
1: {deviceId: "b183634b059298f3692aa7e5871e6a463127701e21e320742c48bda99acdf925", label: "Built-in Microphone", kind: "audioInput"}
2: {deviceId: "4b441035a4db3c858c65c30eabe043ae1967407b3cc934ccfb332f0f6e33a029", label: "Built-in Output", kind: "audioInput"}
3: {deviceId: "05415e116b36584f848faeef039cd06e5290dde2e55db6895c19c8be3b880d91", label: "FaceTime HD Camera", kind: "videoInput"}
length
:4 __proto__:Array(0)

而您可以使用 navigator.mediaDevices.enumerateDevices()

获取它们

有什么指点吗?

披露,我是 TokBox 的员工 :)。 OpenTok 当前不提供指定音频输出设备的方法。这仍然是一个实验性的 API,并且只适用于 Chrome。当 API 标准化并获得更广泛的浏览器支持时,我们将使它变得更容易。

与此同时,使用本机 WebRTC 很容易做到这一点。在 https://webrtc.github.io/samples/src/content/devices/multi/ the source code can be found at https://github.com/webrtc/samples/blob/gh-pages/src/content/devices/multi/js/main.js

有一个很好的示例

总之,您使用了您发现的 enumerateDevices 方法。然后在视频元素 https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/setSinkId

上使用 setSinkId() 方法

您可以通过在订阅者上收听 videoElementCreated 事件来访问 videoElement,如下所示:

subscriber.on('videoElementCreated', (event) => {
  if (typeof event.element.sinkId !== 'undefined') {
    event.element.setSinkId(deviceId)
    .then(() => {
      console.log('successfully set the audio output device');
    })
    .catch((err) => {
      console.error('Failed to set the audio output device ', err);
    });
  } else {
    console.warn('device does not support setting the audio output');
  }
});

所以, @Adam Ullman 给出的答案不再有效,因为在视频元素旁边创建了一个单独的音频元素,阻止我们使用视频元素的 setSinkId 方法。

我找到了一个解决方案,包括从视频中找到音频元素并使用它自己的 setSinkId。 代码:

  const subscriber_videoElementCreated = async event => {
    const videoElem = event.element;
    const audioElem = Array.from(videoElem.parentNode.childNodes).find(child => child.tagName === 'AUDIO');
    if (typeof audioElem.sinkId !== 'undefined') {
      try {
        await audioElem.setSinkId(deviceId);
      } catch (err) {
        console.log('Could not update speaker ', err);
      }
    }
  };

OpenTok(现在是 Vonage)现在提供 API 来在 2.22 中完全做到这一点。 并非所有浏览器 (Safari) 都支持它,但对于支持 setSinkID 的浏览器,现在有一个统一的 API 可以方便地包装功能。

https://tokbox.com/developer/guides/audio-video/js/#setAudioOutput