Skip to contentSkip to navigationSkip to topbar
On this page

Voice JS SDK v1: Twilio.Device


(information)

Info

The Twilio Client JavaScript SDK has been renamed to Twilio Voice JavaScript SDK.

(warning)

Warning

You're viewing the 1.X version of the Voice JavaScript SDK (formerly called Twilio Client). Click here for information on how to migrate to the 2.X version.

The Twilio.Device object is available when twilio.js is included in your page. It represents a soft device, the client that provides connections into Twilio.

  • API Reference
    • Twilio.Device - Twilio.Device is your main entry point for making and receiving calls using twilio.js.
    • Twilio.Device.audio - Twilio.Device.audio allows you to configure the audio routing and sound playback behavior of your Twilio.Device.
  • Deprecated Methods

Method Reference

method-reference page anchor

Twilio.Device

twilio-device page anchor

The following is a list of methods available on Twilio.Device:

constructor([token], [params])

constructor page anchor

As of 1.5.0, the Twilio.Device class can be constructed directly rather than used as a singleton via the Twilio.Device global. Using this method, multiple Device instances can operate on the same page simultaneously. If a token is passed, Device.setup() will be run on construction with the passed token and options. Otherwise, the new Device will wait for Device.setup(token, options) to be called before initiating a signaling connection.

1
const device = new Twilio.Device();
2
device.setup(token, options);
3
4
// or (deprecated singleton behavior)...
5
6
Twilio.Device.setup(token, options);

.setup( token, [params] )

setup page anchor

Initialize Twilio.Device with an Access Token (see Twilio Access Tokens). The token you provide will activate the Device, give it an identity, grant it privileges to make and receive inbound and/or outbound calls, and associate it with a specific Twilio application. You should call this before anything else. If your token allows inbound client connections, the device will start listening for new connections when you call .setup().

(warning)

Warning

The maximum number of characters for the identity provided in token is 121. The identity may only contain alpha-numeric and underscore characters. Other characters, including spaces, or exceeding the maximum number of characters, will result in not being able to place or receive calls.

Best Practice Note
best-practice-note page anchor

Browsers are cracking down on unwarranted background audio. As a result, browsers are progressively moving toward requiring a user gesture before allowing audio to play on a page. Twilio recommends calling Device.setup() in response to a user gesture, such as a click. One popular and intuitive way to implement this is to add a "ready" button that will initiate the Device and show the dialer once clicked.

.setup()'s params argument takes a JavaScript object containing configuration settings. Available settings are listed below:

PropertyDefaultDescription
allowIncomingWhileBusyfalseWhen set to true, Device's default behavior of silently ignoring the incoming call is removed, and the incoming call will instead cause Device to emit an "incoming" event. If accepted, the prior active call will be immediately disconnected, and the incoming call will be accepted, replacing the prior active call.
appNamenullA name for the application that is instantiating the Device. This is used to improve logging in Insights by associating Insights data with a specific application, particularly in the case where one account may be connected to by multiple applications.
appVersionnullA version for the application that is instantiating the Device. This is used to improve logging in Insights by associating Insights data with a specific version of the given application. This can help track down when application-level bugs were introduced.
audioConstraintstrueCan be true or MediaTrackConstraints. Set this property to select a specific microphone, or turn off features like auto-gain control, for the entire Twilio.Device. Each web browser implements a different set of MediaTrackConstraints, so consult your browser's implementation of getUserMedia for further details. This property can also be overridden for each Twilio.Connection. See also our knowledge base article on audioConstraints(link takes you to an external page). Note: If an input device is selected using Device.audio.setInputDevice, this parameter will be ignored and the set input device will be used instead.
backoffMaxMs20000The maximum amount of time, in milliseconds, to wait between websocket reconnects. The SDK uses an exponential backoff, so initially reconnection will be attempted much faster (100ms). The minimum acceptable value here is 3000.
codecPreferences['pcmu', 'opus']An ordered list of preferred codecs. Currently, 'pcmu' and 'opus' are supported. PCMU will remain default until the next breaking release, however we recommend testing and using Opus as it can provide better quality for lower bandwidth, particularly noticeable in poor network conditions.
closeProtectionfalseCan be boolean or string. Setting this property to true will enable a dialog prompt with the text "A call is currently in progress. Leaving or reloading this page will end the call." when closing a page which has an active connection. Setting the property to a string will change the text of the message prompt. NOTE: Where custom text is not supported on the browser, Twilio will display the browser's default dialog.
debugfalseCan be true or false. Set this property to true to enable debug logging in your browser console. This can be overridden using loglevel APIs. Please see SDK Logger section for details.
dscptrueSpecifies whether Twilio Client will ask WebRTC to set the Differentiated Services field in the packet headers for all WebRTC traffic.
edgeroamingThe Edge location to connect to. In case edge is of type array, it should contain the list of edge strings sorted by priority order where the first element has the highest priority and the last element has the lowest priority. The array will be used to provide auto fallback functionality. The edge that the SDK connected to can be read from Twilio.Device using the read-only property Twilio.Device.edge. Please see documentation on edges for more details.
enableIceRestartfalseWhen set to true, allows for detecting when media connection fails which will trigger automatic media reconnection, and for detecting when media connection is restored, as well as the Connection#reconnecting and Connection#reconnected` events.
enableRingingStatefalseWhen set to true, the new ringing state and Connection#ringing event will be enabled for calls this Device makes. These features are intended to be used alongside the answerOnBridge Dial property (eg: <Dial answerOnBridge=true></Dial>) to provide better SDK feedback on the call status.
enumerateDevicesnullPass a custom enumerateDevices function to override what Twilio uses when requesting a list of available media input and output devices.
fakeLocalDTMFfalseIf true, replaces default DTMF tones with mock DTMF tones. This prevents double-tones in some cases. This will become default in the next breaking release.
forceAggressiveIceNominationfalseAn experimental feature for Chrome browser to enable Aggressive ICE Candidate Nomination. This feature can be enabled by setting it to true. If your deployment is on devices with one network interface and your RTT to Twilio's Servers is typically greater than 96 milliseconds, this feature may help reduce call connect time. As this is an experimental feature, we don't recommend enabling this until after testing it thoroughly in your deployment.
getUserMedianullPass a custom getUserMedia function to override what Twilio uses to create an input MediaStream.
iceServersnullAn array of custom ICE servers(link takes you to an external page) to use to connect media. If you have custom Twilio TURN servers from Twilio NTS, you can specify them here.
maxAverageBitratenullMax average bitrate to better control how much bandwidth your VoIP application should use. See RFC-7587 section 7.1(link takes you to an external page). Only applicable when using Opus codec. By default, the Opus codec is set up with a transmission rate of around 32 kbps (40-50kbps on the wire). Max Average Bitrate can be set to as low as 6,000bps and as high as 51,000 bps. Values outside this range are ignored and the default Opus operation mode is used. Lowering the max average bitrate impacts audio quality. We don't recommend setting max average bitrate to a value below 8,000 bps. On the other hand, setting values over 32,000 bps will have negligible audio quality improvements.
regiongllThe region parameter is now deprecated. Please use Twilio.Device.Options.edge instead. Specifies which Twilio Data Center to use when registering, initiating calls, and receiving calls. See this page for the list of available regions, and their IP address ranges
rtcConfigurationnullPass a custom RTCConfiguration object to override what Twilio uses to create RTCPeerConnections.
RTCPeerConnectionnullPass a custom RTCPeerConnection class to override what Twilio uses to create RTCPeerConnections.
soundsnullAn object mapping sound names (property) to custom URLs (string value). Note that incoming ringtone will loop for at least 2 seconds and as long as the incoming call is pending. All other sounds will play once; DTMF tones will be cut short if they exceed 1 second, while outgoing and disconnect sounds will be cut short if they exceed 3 seconds. See the list of all available sound properties and their default values below.
warningstrueCan be true or false. Set this property to false to disable logging warnings to your browser console. This can be overridden using loglevel APIs. Please see SDK Logger section for details.

For example:

Twilio.Device.setup(token); // use the default parameters

Or using params:

1
// enable debug logging and use default values for all other parameters
2
Twilio.Device.setup(token, { debug: true });

Or using custom sounds:

1
Twilio.Device.setup(token, {
2
sounds: {
3
incoming: 'http://mysite.com/incoming.mp3',
4
outgoing: 'http://mysite.com/outgoing.mp3',
5
dtmf8: 'http://mysite.com/funny_noise.mp3'
6
}
7
}

Or specify an Edge location to connect to:

1
// edge as a string
2
Twilio.Device.setup(token, { edge: 'ashburn' });
3
4
// edge with auto fallback functionality
5
Twilio.Device.setup(token, { edge: ['ashburn', 'sydney' ] });
6
7
// edge with auto fallback functionality for private interconnect
8
Twilio.Device.setup(token, { edge: ['ashburn', 'san-jose-ix' ] });

Available sound properties

available-sound-properties page anchor
Property nameDefault filenameDefault value(s)
incomingincomingshouldLoop: true
outgoingoutgoingmaxDuration: 3e3
disconnectdisconnectmaxDuration: 3e3
dtmf1dtmf-1maxDuration: 1e3
dtmf2dtmf-2maxDuration: 1e3
dtmf3dtmf-3maxDuration: 1e3
dtmf4dtmf-4maxDuration: 1e3
dtmf5dtmf-5maxDuration: 1e3
dtmf6dtmf-6maxDuration: 1e3
dtmf7dtmf-7maxDuration: 1e3
dtmf8dtmf-8maxDuration: 1e3
dtmf9dtmf-9maxDuration: 1e3
dtmf0dtmf-0maxDuration: 1e3
dtmfsdtmf-starmaxDuration: 1e3
dtmfhdtmf-hashmaxDuration: 1e3

.connect( [params [, audioConstraints]] )

connect page anchor

Attempts a new connection to the Twilio application that you associated with this Device's Access Token when you called .setup() (see Access Tokens for more information).

The optional params argument is a JavaScript object which will be passed to your application as POST/GET parameters. Note, the total length of all parameters passed in must not exceed 800 bytes. See How to Share Information Between Your Applications for more information.

(warning)

Warning

Your application should not assume that these parameters are safe since any user can call this function with whatever parameters they want.

For example, the following code will pass the parameters agent=Smith and location=Matrix to the Twilio application associated with this Device's Access Token.

1
var connection = Twilio.Device.connect({
2
agent: "Smith",
3
location: "Matrix"
4
});
5

You can also specify an audioConstraints object to change the behavior of the local media stream during this call. You can use this to select a specific microphone, or turn off features like auto-gain control. Each web browser implements a different set of MediaTrackConstraints which may be used as audioConstraints, so consult your browser's implementation of getUserMedia for further details.

1
var audioConstraints = {
2
optional: [{ sourceId: 'XXX' }]
3
};
4
5
var connection = Twilio.Device.connect(null, audioConstraints);

The .connect() method returns a Twilio.Connection object. You can end the connection by calling its .disconnect() method.

When you call .connect(), the client will attempt a new connection to the Twilio Application you use in your Twilio.Device's access token. This application can do whatever you like: Make a phone call to a phone number or Twilio Client address, start a conference call, interact with an IVR, etc.

For example, if your application's VoiceUrl returns the following TwiML:

1
<Response>
2
<Dial callerId="+1888XXXXXXX">
3
415-867-5309
4
</Dial>
5
</Response>

then your device will make a call to 415-867-5309 every time you call .connect().

All of TwiML is available to your client applications.

You can use the params passed to the application in .connect() to dynamically generate the right TwiML for your app. For example, you could do the following in your JavaScript code:

1
var number = '5558675309';
2
var connection = Twilio.Device.connect({
3
phone: number
4
});

And in the web application that generates your TwiML, retrieve the phone parameter from the HTTP request and insert into your TwiML as follows:

1
<Response>
2
<Dial callerId="+1888XXXXXXX">
3
5558675309
4
</Dial>
5
</Response>

.activeConnection()

activeconnection page anchor

Returns the active connection object. Connection objects can be used to perform operations on the connection like mute, unmute, sending DTMF digits, etc.

Destroys the device. Terminates active and pending connections, and cleans up all event listeners attached to the Device, after triggering the offline event handler. Device will not be able to make or receive new connections until you call Device.setup() again.

Terminates the active connection. This will trigger the disconnect event handler. It will not prevent new incoming connections.

Return the status of the device. The status will be one of the following strings:

Status nameDescription
readyThe device is currently connected to Twilio and has a valid Access Token.
offlineThe device is either not connected to Twilio or has an expired/invalid Access Token.
busyThe device is connected to Twilio, has an active connection, and cannot receive incoming connections or attempt outgoing connections.

.runPreflight(token, options)

runpreflight page anchor

Returns a PreflightTest object representing a test call to Twilio which provides information to help troubleshoot call related issues. For example:

1
import { Device, PreflightTest } from 'twilio-client';
2
3
const preflightTest = Device.runPreflight(token, options);
4
5
preflightTest.on(PreflightTest.Events.Completed, (report) => {
6
console.log(report);
7
});
8
9
preflightTest.on(PreflightTest.Events.Failed, (error) => {
10
console.log(error);
11
});

The token parameter is passed directly to the Device's constructor and will be used to connect to a TwiML app that you associated with your token. In order to get better results, the TwiML app should be able to record audio from a microphone and play it back to the browser. Please see Preflight Test TwiML Apps for details.

The options parameter is a JavaScript object containing configuration settings. Available settings are listed below:

PropertyDefaultDescription
codecPreferences['pcmu', 'opus']An ordered list of preferred codecs.
debugfalseSet this property to true to enable debug logging in your browser console.
edgeroamingSpecifies which Twilio edge to use when initiating the test call. Please see documentation on edges.
fakeMicInputfalseIf set to true, the test call will ignore microphone input and will use a default audio file. If set to false, the test call will capture the audio from the microphone.
signalingTimeoutMs10000Amount of time to wait for setting up signaling connection.
iceServersnullAn array of custom ICE servers(link takes you to an external page) to use to connect media. If you provide both STUN and TURN server configurations, the test will detect whether a TURN server is required to establish a connection.

Note that any event handlers set here will be removed when calling Device.destroy().

.on('cancel', handler(connection))

cancel page anchor

This is triggered when an incoming connection is canceled by the caller before it is accepted by the Twilio Client device.

The handler function receives a Twilio.Connection object as an argument. Since this Connection object represents an inactive connection, you'll probably just want to use the event to update your application's UI, then throw away the Connection and wait for the next call.

.on('connect', handler(connection))

connect-handler page anchor

This is triggered when a connection is opened, whether initiated using .connect() or via an accepted incoming connection.

The handler function receives a Twilio.Connection object as an argument.

.on('disconnect', handler(connection))

disconnect page anchor

Fired any time a Connection is closed. The handler function receives the Twilio.Connection object that was just closed as an argument.

.on('error', handler(error))

error page anchor

Emitted when any device error occurs. These may be errors in your request, your token, connection errors, or other application errors. See the Twilio Client error code reference for more information. Using the error handler is a great way to debug your application and help catch mistakes in your code.

The handler function receives an error object as an argument. The error object may include the following properties:

PropertyDescription
messageA string describing the error.
codeA numeric error code described in the Twilio Client error code reference.
connectionA reference to the Twilio.Connection object that was active when the error occurred.
twilioErrorWhen applicable, errors emitted now contain this twilioError field, providing more information about the error. This twilioError represents the new TwilioError format that will become the default Error format in the next major release of this SDK. To get a list of possible twilioErrors, please visit this page(link takes you to an external page).
1
Twilio.Device.on('error', function(error) {
2
console.log(error.message);
3
});

.on('incoming', handler(connection))

incoming page anchor

This is triggered whenever an incoming connection from an outbound REST call or a TwiML <Dial> to this device is made.

(warning)

Warning

Remember, to enable incoming connections you must give your device a name using the Access Token you provided in .setup(token). See the Client Quickstart on receiving incoming connections for more information.

The handler function receives a Twilio.Connection object as an argument. This connection will be in state pending until you call .accept() on it.

1
Twilio.Device.on('incoming', function(connection) {
2
connection.accept();
3
// do awesome ui stuff here
4
// $('#call-status').text("you're on a call!");
5
});

.on('offline', function(device))

offline page anchor

This is triggered when the connection to Twilio drops or the device's token is invalid/expired. In either of these scenarios, the device cannot receive incoming connections or make outgoing connections. If the token expires during an active connection the offline event will be fired, but the connection will not be terminated. In this situation you will have to call Twilio.Device.setup() with a valid token before attempting or receiving the next connection.

The handler function receives the Twilio.Device object as its sole argument.

(warning)

Warning

We strongly recommend you implement an offline event handler before putting your application into production so that your application handles these scenarios gracefully.

.on('ready', function(device))

ready page anchor

This is initially triggered when all operations in .setup() have completed and the device is ready and online. It will be triggered again if the device goes offline and comes back online (i.e. the connection drops and returns).

The handler function receives the Twilio.Device object as its sole argument.

1
Twilio.Device.on('ready', function(device) {
2
// The device is now ready
3
console.log("Twilio.Device is now ready for connections");
4
});

Device.isSupported is a Boolean value which indicates whether WebRTC is supported by the browser or not. If false, it's an indicator that Device.setup should not be called or else it will throw an unsupported exception.

Device.packageName returns the npm package name. This can be used to get the logger instance used by the SDK. See SDK Logger for details.

Example:

1
import { getLogger } from 'loglevel';
2
const logger = getLogger(Device.packageName);

Device.version returns the current version of the SDK.


By default, the SDK automatically reconnects the WebSocket connection to the same edge location when it is unreachable, or when the SDK encounters a network error that results in a WebSocket disconnect. But if Twilio.Device.Options.edge parameter is supplied as an array of edge names, the SDK will enable automatic Edge fallback functionality. The diagram below illustrates the logic that is executed to perform the fallback.

edge-fallback-diagram.

During initialization, the SDK will use the first edge name in the Twilio.Device.Options.edge array. If the SDK encounters an error that results in a WebSocket disconnect with error code 1006 or 1015(link takes you to an external page), the SDK will attempt reconnection to the next Edge in the array using an exponential backoff timer with an initial value of 1+random(5) and a maximum of 20 seconds. This maximum delay can be configured via Twilio.Device.Options.backoffMaxMs parameter.

If the SDK encounters an error while already connected to an edge server, the SDK will try to reconnect to the same edge once before attempting to connect to the next edge.

The following table provides common scenarios for when a fallback may occur:

ScenarioExpected Behavior
Initialize with edge: ["ashburn"]This behaves exactly the same as initializing with edge: "ashburn". In this scenario, the SDK will always attempt to reconnect to ashburn whenever the WebSocket is disconnected.
The first edge name specified in the edge array is unreachable. • ashburn becomes unreachable • Initialize with edge: ["ashburn", "sydney"]The SDK will attempt to connect to ashburn. Since ashburn is unreachable, the attempt will fail. The SDK will then attempt to connect to sydney.
All edge endpoints are unreachable, then one region becomes available after a few seconds. • ashburn, sydney, and dublin becomes unreachable • Initialize with edge: ["ashburn", "sydney", "dublin"] • sydney becomes available, and the rest of the regions are still unreachableThe SDK will attempt to connect to ashburn. Since ashburn is unreachable, the attempt will fail. The SDK will then attempt sydney and will fail again. Then dublin will be attempted and fail. Once the SDK reaches the last edge name, it will loop back to the first edge name ashburn, and will keep cycling through the edge names until one edge endpoint becomes available. If sydney becomes available, the SDK will be connected to sydney once the loop reaches it.
All edges are available and the edge the SDK is connected to suddenly becomes unreachable. • Initialize with edge: ["ashburn", "sydney", "dublin"] • SDK is now connected to ashburn. • ashburn goes down and becomes unreachableIf you are connected to ashburn and it suddenly becomes unreachable, the SDK will attempt to connect to ashburn once. If the attempt fails, the SDK will attempt to connect to the next edge, which is sydney.

It's important to note that "unreachable" in these scenarios means the SDK failed to establish a WebSocket connection to the edge endpoint which resulted in error code 1006 or 1015(link takes you to an external page). The error code 1015 is a WebSocket close event which is raised when the connection fails to perform a TLS handshake. This happens if the server certificate is invalid or cannot be verified. While the error code 1006 is raised when the connection was dropped unexpectedly and there is no close frame received from the server. The following are common issues that causes 1006:

  • The domain name cannot be resolved by the DNS
  • The network cannot reach the endpoint due to, for example, a misconfigured firewall
  • The client becomes offline due to, for example, the local device losing network connectivity, and
  • In an unlikely and very rare scenario, the Edge and standby servers are down

Prior to version 1.10.0, Voice Client JS logging could only be configured during Device.setup using debug and warnings flag. Starting 1.10.0, Voice Client JS exposes a loglevel(link takes you to an external page) based logger which allows for runtime logging configuration that includes setting the log level to "trace", "debug", "info", "warn" and "error". Loglevel(link takes you to an external page) is a versatile logger library that includes level-based logging and filtering, and provides a plugin API to enable functionality such as sending the log messages to a log server.

For example, to enable logging:

1
import { getLogger } from 'loglevel';
2
3
const logger = getLogger(Device.packageName);
4
// Set log level on subsequent page loads and refreshes
5
logger.setLevel('DEBUG');

Twilio.Device.audio

audio page anchor

The Device.audio object lets you control the way Twilio Client interacts with speaker and microphone resources. Device.audio is an [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter), and as such its events can be subscribed to viaDevice.audio.on(eventName, handler).

NOTE: Many of audio features are browser-dependent.

Currently Chrome 49+ is the only browser that fully supports Twilio.Device.audio.

Audio output selection requires support for setSinkId(link takes you to an external page). At the time of writing, this method is only supported in Chrome 49 and above, and Microsoft Edge. As Firefox adds support for these APIs, twilio.js will be updated to provide support. Although Edge supports setSinkId, it is not yet fully supported in this API.

Audio input selection requires support for AudioContext(link takes you to an external page). This feature is supported in latest modern browsers (Chrome, Firefox, Edge), however twilio.js has not completed implementation in Firefox and Edge. Support is coming soon.

If these features are used in a browser that does not support them, the get method will return an empty Set, whereas the set and test methods will return a rejected Promise.

.audio.setAudioConstraints(audioConstraints)

audiosetaudioconstraintsaudioconstraints page anchor

Set the MediaTrackConstraints(link takes you to an external page) to be applied on every getUserMedia call for new input device audio. Any deviceId specified here will be ignored. Instead, device IDs should be specified using .audio.setInputDevice(). The returned Promise resolves when the media is successfully reacquired, or immediately if no input device is set.

1
device.audio.setAudioConstraints({ echoCancellation: true });
2
await device.audio.setInputDevice('default');
3
// Now we have a live input audio track, opened with echoCancellation:true
4
device.audio.setAudioConstraints({
5
autoGainControl: false,
6
echoCancellation: false,
7
noiseSuppression: false,
8
}).then(() => {
9
// We successfully applied the new constraints and should automatically hear the difference.
10
// Future calls to setInputDevice will also use these constraints until they're cleared.
11
}, err => {
12
// Something went wrong, most likely err is an OverconstrainedError. Let's roll back.
13
await device.audio.unsetAudioConstraints();
14
// We should now have a working input audio track again
15
});

.audio.setInputDevice(id)

audiosetinputdeviceid page anchor

Set the current input device by deviceId. Once this is set, the input device will be used in the current call, if any, and used by default for any subsequent calls. In addition, whenever an inputDevice is set, the Device.audio#inputVolume event will fire on every animation frame(link takes you to an external page). Returns a Promise that resolves if the input device was set successfully.

Note: This is not supported in Firefox (as recent as 51) due to its lack of support for multiple input devices.

1
Twilio.Device.audio.setInputDevice('default').then(function() {
2
console.info('Success!');
3
});

.audio.unsetAudioConstraints()

audiounsetaudioconstraints page anchor

Unset the MediaTrackConstraints to be applied on every getUserMedia call for new input device audio. The returned Promise resolves when the media is successfully reacquired, or immediately if no input device is set.

.audio.unsetInputDevice(id)

audiounsetinputdeviceid page anchor

Unset the active input device. This will stop the Device.audio#inputVolume polling, and stop the input stream.

1
Twilio.Device.audio.unsetInputDevice().then(function() {
2
console.info('Success!');
3
});

.audio.audioConstraints

audioaudioconstraints page anchor

The currently set input audio MediaTrackConstraints(link takes you to an external page) set by setAudioConstraints(). Starts as null.

.audio.availableOutputDevices

audioavailableoutputdevices page anchor

A Map(link takes you to an external page) containing the MediaDeviceInfo(link takes you to an external page) object of all available output devices (hardware devices capable of outputting audio), indexed by deviceId.

Note: Due to browser-imposed security restrictions, MediaDeviceInfos available in availableOutputDevices may contain auto-generated labels (e.g. "Unknown Audio Output Device 1"), or an incomplete / empty list of devices, until the user grants the application access to these resources in response to a call to the browser's getUserMedia()(link takes you to an external page) API. In an effort to reduce device fingerprinting, all major browsers are getting more strict in this regard. We strongly recommend your application calls getUserMedia()(link takes you to an external page) before rendering your input / output device selection UI for the cleanest user experience.

Also Note: Firefox (as recent as 51) does not list any audiooutput devices, and Edge (as recent as 38) does not label its audiooutput devices even after user permission is granted.

After the user accepts the getUserMedia() prompt, the ``AudioHelper#deviceChange event will be fired to indicate that the application UI should be updated.

1
Twilio.Device.audio.availableOutputDevices.forEach(function(device, id) {
2
console.info('Available device:', id, '(labeled', device.label, ')');
3
});

.audio.availableInputDevices

audioavailableinputdevices page anchor

A Map(link takes you to an external page) containing the MediaDeviceInfo(link takes you to an external page) object of all available input devices (hardware devices capable of providing an input audio stream), indexed by deviceId.

Note: Due to browser-imposed security restrictions, MediaDeviceInfos available in availableInDevices may contain auto-generated labels (e.g. "Unknown Audio Input Device 1"), or an incomplete / empty list of devices, until the user grants the application access to these resources in response to a call to the browser's getUserMedia()(link takes you to an external page) API. In an effort to reduce device fingerprinting, all major browsers are getting more strict in this regard. We strongly recommend your application calls getUserMedia()(link takes you to an external page) before rendering your input / output device selection UI for the cleanest user experience.

After the user accepts the getUserMedia() prompt, the ``AudioHelper#deviceChange event will be fired to indicate that the application UI should be updated.

A MediaDeviceInfo(link takes you to an external page) representing the input device selected by .audio.setInputDevice(), or null.

Twilio.Device.audio.speakerDevices

twiliodeviceaudiospeakerdevices page anchor

speakerDevices is an AudioOutputCollection that controls which output devices are used to play standard speaker sounds: the ringtone you hear when initiating a call, the disconnect sound, DTMF tones the user might press and the audio received from the remote participant. Changing this set of devices will switch the device(s) used for these sounds. If you change these during an active call, the remote participant's audio will immediately be played through the new set of outputs.

Note: This is not supported in Firefox (as recent as 51) or Edge (as recent as 38) due to their lack of support for HTMLAudioElement.setSinkId().

1
// Returns a Set<MediaDeviceInfo> of the current speakerDevices
2
Twilio.Device.audio.speakerDevices.get();
3
// Set the active device to the default
4
Twilio.Device.audio.speakerDevices.set('default');
5
// Set the active devices to the default and ABC123
6
Twilio.Device.audio.speakerDevices.set(['default', 'ABC123']);

Twilio.Device.audio.ringtoneDevices

twiliodeviceaudioringtonedevices page anchor

``ringtoneDevices is an AudioOutputCollection that controls which output devices are used to play the ringing sound when receiving an incoming call. Changing this set of devices will switch the devices used for the incoming call sound.

Note: This is not supported in Firefox (as recent as 51) or Edge (as recent as 38) due to their lack of support for HTMLAudioElement.setSinkId().

1
Twilio.Device.audio.ringtoneDevices.get(); // Returns a Set<MediaDeviceInfo>
2
Twilio.Device.audio.ringtoneDevices.set('default'); // Set active device
3
Twilio.Device.audio.ringtoneDevices.set(['default', 'ABC123']); // Set active devices
4
Twilio.Device.audio.ringtoneDevices.test(); // Test with 'outgoing' sound
5
Twilio.Device.audio.ringtoneDevices.test('cowbell.mp3'); // Test with custom sound

Twilio.Device.audio.speakerDevices.test() and Twilio.Device.audio.ringtoneDevices.test()

twiliodeviceaudiospeakerdevicestest-and-twiliodeviceaudioringtonedevicestest page anchor

Use the test() method on the speakderDevices or ringtoneDevices collections to play a test sound. This is a great way to let your user evaluate whether the device is working as expected by giving them audible feedback on the device configuration.

1
// Test that the devices have been set properly by playing 'outgoing' sound...
2
Twilio.Device.audio.speakerDevices.test();
3
// ... or test playback using a custom sound
4
Twilio.Device.audio.speakerDevices.test('cowbell.mp3');

event: Twilio.Device.audio#deviceChange

event-twiliodeviceaudiodevicechange page anchor
.audio.on('deviceChange', handler(lostActiveDevices))

Register a handler that will be fired whenever a new audio device is found, an existing audio device is lost or the label of an existing device is changed. This typically happens when the user plugs in or unplugs an audio device, like a headset or a microphone. This will also trigger after the customer has given access to user media via ``getUserMedia for the first time, as the labels will become populated. If you want to allow users to choose a specific audio device in your application's UI, attach a listener to this event.

Note that this does not detect a customer plugging in headphones or other speakers through the headphone jack, as the headphone jack only redirects audio from the internal audio device.

The parameter, lostActiveDevices, is an array of [MediaDeviceInfo](https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo) objects that represents all devices that were currently active in either.speakerDevices or ``.ringtoneDevices at the time they were lost, if any. A non-empty array is an indicator that the user's experience was likely affected by this event.

event: Twilio.Device.audio#inputVolume

event-twiliodeviceaudioinputvolume page anchor
.audio.on('inputVolume', handler(volume))

Register a handler that will be fired every animation frame(link takes you to an external page) with the current volume of the selected input device, if one is set. The handler will be invoked up to 60 times per second, and will scale down dynamically on slower devices to preserve performance. The handler receives volume as a percentage of maximum volume represented by a floating point number between 0.0 and 1.0, inclusive. This value represents a range of relative decibel values between -100dB and -30dB.

Note: This will never in Firefox (as recent as 51) as there is no supported way to set the input device.

Twilio.AudioOutputCollection

twilioaudiooutputcollection page anchor

Both speakerDevices and ringtoneDevices are instances of AudioOutputCollection . An AudioOutputCollection represents active audio devices, and can be updated to redirect speaker and ringtone sounds to different devices in realtime.

audioOutputCollection.get()

audiooutputcollectionget page anchor

Get a Set containing MediaDeviceInfo objects representing the active devices in the collection.

audioOutputCollection.set( deviceId | deviceIds )

audiooutputcollectionset-deviceid--deviceids- page anchor

Replace the active devices in the collection by passing one or more device IDs. Returns a Promise, which is fulfilled if the device(s) were set successfully and rejected if:

  • Output selection is not supported by the browser or
  • A specified deviceId wasn't found or
  • No deviceIds were specified

audioOutputCollection.test( soundUrl )

audiooutputcollectiontest-soundurl- page anchor

Test the active devices by playing a sound through them. Optionally, a URL can be passed to play a custom test sound. Returns a Promise, which is fulfilled if the devices were set successfully and rejected if:

  • Output selection is not supported by the browser or
  • There are no active devices or
  • Client detects one or more devices failed to play
1
var speakerDeviceSelect = document.getElementById('speaker-devices');
2
3
// When a device is found or lost, update a multi-select element with the
4
// new set of available devices.
5
Twilio.Device.audio.on('deviceChange', function updateAvailableDevices() {
6
speakerDeviceSelect.innerHtml = '';
7
8
Twilio.Device.audio.availableOutputDevices.forEach(function(device, id) {
9
var deviceOption = document.createElement('option');
10
deviceOption.label = device.label;
11
deviceOption.setAttribute('data-id', id);
12
13
// If the device is present in Device.audio.speakerDevices, then it is
14
// currently active, and should be selected in the multi-select element.
15
var speakerDevices = Twilio.Device.audio.speakerDevices.get();
16
speakerDevices.forEach(function(spkDev) {
17
if (spkDev.deviceId === id) {
18
deviceOption.setAttribute('selected', 'selected');
19
}
20
});
21
22
speakerDeviceSelect.appendChild(deviceOption);
23
});
24
});
25
26
// When a device is selected or unselected, update Device.audio.speakerDevices
27
// with the devices the user selected to immediately change where the audio
28
// is playing from.
29
speakerDeviceSelect.addEventListener('change', function() {
30
var selectedDeviceIds = [].slice.call(speakerDevices.childNodes)
31
.filter(function(node) { return node.selected; })
32
.map(function(node) { return node.getAttribute('data-id'); });
33
34
Twilio.Device.audio.speakerDevices.set(selectedDeviceIds);
35
});

These getters/setters were moved over from the deprecated ``Device.sounds API. If a sound is disabled, it will not be played through any output device.

.audio.incoming( [bool] )

Enable or disable the incoming event sound.

.audio.incoming()

Returns a Boolean indicating whether the incoming sound is enabled or disabled.

.audio.outgoing( [bool] )

Enable or disable the outgoing event sound.

.audio.outgoing()

Returns a Boolean indicating whether the outgoing sound is enabled or disabled.

.audio.disconnect( [bool] )

Enable or disable the disconnect event sound.

.audio.disconnect()

Returns a Boolean indicating whether the disconnect sound is enabled or disabled.


twilio.js 1.3 and below exposed a sounds object on the Device. In twilio.js 1.4 and above,sounds and all of the methods defined on sounds have been moved toaudio. sounds and the old versions of these methods remain available in twilio.js 1.4, but calling the methods onsounds will generate a deprecation warning. We strongly encourage you to begin using ``audio.

Additionally, Twilio Client is moving toward the standard EventEmitter(link takes you to an external page) interface, meaning events should be managed with .on(eventName, handler) and .removeListener(eventName, handler), replacing our legacy handlers (such as .accept(handler), .error(handler), etc...). The following methods are deprecated:

1
Device.cancel(handler)
2
Device.connect(handler)
3
Device.disconnect(handler)
4
Device.error(handler)
5
Device.incoming(handler)
6
Device.offline(handler)
7
Device.ready(handler)

These have been replaced with the following events:

1
Device.on('cancel', handler)
2
Device.on('connect', handler)
3
Device.on('disconnect', handler)
4
Device.on('error', handler)
5
Device.on('incoming', handler)
6
Device.on('offline', handler)
7
Device.on('ready', handler)

Need some help?

Terms of service

Copyright © 2024 Twilio Inc.