Skip to contentSkip to navigationSkip to topbar
On this page

TwiML™️ Voice: <Stream>


The <Stream> TwiML noun is used in conjunction with either <Start> or <Connect>. When Twilio executes the <Start><Stream> or <Connect><Stream> instruction during a Call, Twilio forks the raw audio stream of the Call and streams it to your WebSocket(link takes you to an external page) server in near real-time.

This page covers <Stream>'s supported attributes and provides sample code for generating <Stream> TwiML instructions with a Helper Library.

<Stream> is part of Twilio's Media Streams product. To learn more about Media Streams and how to integrate it with your Voice application, check out the Media Streams Overview page.

<Start><Stream> creates a unidirectional Stream. <Connect><Stream> creates a bidirectional Stream.

Below is a basic example of <Start><Stream>:

Start a MediaStreamLink to code sample: Start a MediaStream
1
const VoiceResponse = require('twilio').twiml.VoiceResponse;
2
3
const response = new VoiceResponse();
4
const start = response.start();
5
start.stream({
6
name: 'Example Audio Stream',
7
url: 'wss://example.com/audiostream',
8
});
9
response.say('The stream has started.');
10
11
console.log(response.toString());

Output

1
<?xml version="1.0" encoding="UTF-8"?>
2
<Response>
3
<Start>
4
<Stream name="Example Audio Stream" url="wss://example.com/audiostream" />
5
</Start>
6
<Say>The stream has started.</Say>
7
</Response>

When Twilio executes this instruction, Twilio forks the audio stream of the current Call and sends it in real-time over a WebSocket connection to the URL specified in the url attribute.

While Twilio is setting up the Media Stream, it also immediately continues with the next TwiML instruction. If there is no instruction, the Call disconnects. Therefore, you should include a TwiML instruction after <Start><Stream> as shown in the example above.

Below is an example of <Connect><Stream>:

Connect call to a bidirectional MediaStreamLink to code sample: Connect call to a bidirectional MediaStream
1
const VoiceResponse = require('twilio').twiml.VoiceResponse;
2
3
const response = new VoiceResponse();
4
const connect = response.connect();
5
connect.stream({ url: 'wss://example.com/audiostream' });
6
response.say(
7
'This TwiML instruction is unreachable unless the Stream is ended by your WebSocket server.'
8
);
9
10
console.log(response.toString());

Output

1
<?xml version="1.0" encoding="UTF-8"?>
2
<Response>
3
<Connect>
4
<Stream url="wss://example.com/audiostream" />
5
</Connect>
6
<Say>This TwiML instruction is unreachable unless the Stream is ended by your WebSocket server.</Say>
7
</Response>

When <Connect><Stream> is used, Twilio does not executing the next set of TwiML instructions. The only way Twilio executes TwiML instructions after <Connect><Stream> is if your server closes the WebSocket connection with Twilio.


Attributes

attributes page anchor

<Stream> supports the following attributes:

Attribute NameAllowed ValuesDefault Value
urlA relative or absolute URL.none
nameOptional. Unique name for the Stream.none
trackOptional. inbound_track, outbound_track, both_tracksinbound_track
statusCallbackOptional. A relative or absolute URL.none
statusCallbackMethodOptional. GET or POSTPOST

url

url page anchor

The url attribute accepts a relative or absolute URL. On successful execution, a WebSocket connection to the URL will be established and audio will start streaming.wss is the only supported protocol.

The url does not support query string parameters. To pass custom key value pairs to the WebSocket, make use of Custom Parameters instead.

Providing a name allows you to reference the Stream directly. This name must be unique per Call. This allows you to stop a Stream by name.

For unidirectional Streams (<Start><Stream>), the track attribute allows you to specify which tracks of a Call to receive, inbound_track, outbound_track, or both_tracks. The default value is inbound_track.

On any given active Call, there are two tracks: an inbound track and an outbound tracks. The naming of these tracks is from Twilio's perspective.

"Inbound" represents the audio Twilio receives from the other party on the Call (e.g., the audio of a caller speaking into their cell phone). If you use inbound_track (or omit the track attribute), your WebSocket endpoint receives inbound media events.

"Outbound" represents the audio generated by Twilio to the Call (this could be audio generated by <Say>, <Play> hold music, or the audio from a child Call). If you use outbound_track, your WebSocket endpoint receives outbound media events.

If both_tracks is used, you will receive both the inbound media event and outbound media event.

For bidirectional Streams (<Connect><Stream>), you can only receive the inbound_track.

The statusCallback attribute takes an absolute or relative URL as value. Whenever a Stream is started or stopped, Twilio sends an HTTP request to this URL with the following parameters:

ParameterDescription
AccountSidThe unique identifier of the Account responsible for this Stream.
CallSidThe unique identifier of the Call.
StreamSidThe unique identifier for this Stream.
StreamNameIf defined, this is the unique name of the Stream. Defaults to the StreamSid.
StreamEventOne of stream-started, stream-stopped, or stream-error (see StreamError for the message).
StreamErrorIf an error has occurred, this will contain a detailed error message.
TimestampThe time of the event in ISO 8601 format(link takes you to an external page).

The HTTP method to use when requesting the statusCallback URL. Default is POST.


It is possible to include additional key value pairs that Twilio then passes along to your WebSocket server. You can do this by using the nested <Parameter> TwiML noun.

Note: The combined length of each <Parameter>'s name and value attributes must be under 500 characters.

Provide Custom Parameters to a MediaStream on creationLink to code sample: Provide Custom Parameters to a MediaStream on creation
1
const VoiceResponse = require('twilio').twiml.VoiceResponse;
2
3
const response = new VoiceResponse();
4
const start = response.start();
5
const stream = start.stream({
6
url: 'wss://mystream.ngrok.io/example'
7
});
8
stream.parameter({
9
name: 'FirstName',
10
value: 'Jane'
11
});
12
stream.parameter({
13
name: 'LastName',
14
value: 'Doe'
15
});
16
17
console.log(response.toString());

Output

1
<?xml version="1.0" encoding="UTF-8" ?>
2
<Response>
3
<Start>
4
<Stream url="wss://mystream.ngrok.io/example">
5
<Parameter name="FirstName" value="Jane" />
6
<Parameter name="LastName" value="Doe" />
7
</Stream>
8
</Start>
9
</Response>

Twilio sends these values to your WebSocket server in the Start message.


If you started a Stream with <Start> and the name attribute, you can use the <Stop> TwiML verb to stop the Stream by name.

Note: The only way you can stop a bidirectional Stream (one that was started with <Connect><Stream>) is to end the call.

Below is some sample TwiML instructions that start the stream using <Start> and the name attribute. The name is my_first_stream.

1
<Start>
2
<Stream name="my_first_stream" url="wss://mystream.ngrok.io/audiostream" />
3
</Start>

You can later use the unique name of my_first_stream to stop the Stream, as shown by the sample TwiML instructions below.

1
<Stop>
2
<Stream name="my_first_stream" />
3
</Stop>

You can also stop a unidirectional Stream via API. Visit the Stream resource API reference page for more information.

Need some help?

Terms of service

Copyright © 2024 Twilio Inc.