'How to select audioOutput with OpenTok

I am building a simple WebRTC app with OpenTok. I need to be able to select camera, audio input and audio output. Currently that doesn't seem easily possible.

See opentok-hardware-setup

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

I am loading OpenTok in my index.html file and opentok-hardware-setup.js.

All looks great and I can select microphone and camera BUT not the speaker out aka audiooutput.

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

From the console, I tried

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

and observed that you can't get the 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)

whereas you can get them using navigator.mediaDevices.enumerateDevices()

enter image description here

Any pointers?



Solution 1:[1]

So, The answer gave by @Adam Ullman is not valid anymore since there is a separate audio element created alongside the video element preventing us to use the setSinkId method of the video element.

I found a solution consisting in finding the audio element from the video one and using its own setSinkId. Code:

  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);
      }
    }
  };

Solution 2:[2]

OpenTok (now Vonage) now provides an API for doing exactly this in 2.22. It is not supported on all browsers (Safari), but for browsers which support setSinkID, there is now a uniform API which wraps the functionality handily.

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Adam Soto
Solution 2 Daniel O'Rorke