Tweaking The Behavior of User Media Streams in Twilio Client

October 10, 2014
Written by
Al Cook
Twilion

Programmable Voice iOS SDK

WebRTC is still an emerging standard, and as such you sometimes run into issues where it behaves differently on different hardware, different browsers, etc.

Today, we updated Twilio Client 1.2 to give you more control over the underlying WebRTC primitives, particularly getUserMedia, which allows you to gain access to the user’s microphone. This new feature allows you to maintain consistent audio quality in different audio environments.

Twilio Client normally takes care of audio issues for you, but sometimes you might encounter device-specific issues where it helps to manually adjust getUserMedia’s parameters. Twilio.js now allows you to pass through specific settings to the underlying WebRTC object.

Here’s one example where this comes in handy. One of our customers found that their audio devices didn’t work properly with Windows auto-gain control (AGC) features. AGC is designed to filter a microphone’s input volume dynamically based on the loudness of the source, so that the other end hears a consistent, even volume.

Unfortunately, one customer found that their AGC didn’t quite live up to its name. Whenever they made a call with Chrome on Windows, the operating system would slowly crank the microphone volume all the way up to 11. This was not an enjoyable experience for the person on the other end.

The source of the problem was that AGC was trying to find the right volume for the microphone, but was getting it wrong.

Thankfully, Twilio Client’s new audioConstraints parameter now allows you to enable or disable features like AGC by passing audio constraints directly to the underlying call to getUserMedia, allowing you to work around unusual, environment-specific problems like this one.

To avoid the “cranking it to 11” problem we previously mentioned, you could use audioConstraints to turn off AGC in Chrome through the googAutoGainControl parameter, as shown below:

 

Twilio.Device.setup(token, {
  audioConstraints: {
    optional: [
      { googAutoGainControl: false }
    ]
  }
});

 

This is just one example where it can be really useful to be able to pass parameters directly to getUserMedia. The new audioConstraints parameter is an optional second argument to Twilio.Device.setup(). Any parameters you pass in here will be sent through to getUserMedia.

For example, you could use audioConstraints to programmatically choose a specific audio device:

 

MediaStreamTrack.getSources(withSources);
 
function gotSources(sourceInfos) {
  var constraints = {};
   
  sources.forEach(function(source) {
    if (source.kind === "audio" && source.label === "My Device") {
      constraints.optional = [
        { sourceId: source.id }
      ];
    }
  });
 
  Twilio.Device.connect(clientParams, constraints);
}

We’ve put a more detailed example here. If you’d like to experiment with what values you can pass through, you can find a fairly comprehensive list of them here.

This feature is now available to everyone using the 1.2 release of twilio.js. Please let us know what uses you find for it!