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 server in near real-time.
This page covers supported attributes for <Stream> and provides sample code for generating <Stream> TwiML instructions with an SDK.
<Stream> is part of the Media Streams product. To learn more about Media Streams and how to integrate it with your Voice application, see Media Streams.
<Start><Stream> creates a unidirectional Stream. <Connect><Stream> creates a bidirectional Stream.
The following is an example of <Start><Stream>:
1const VoiceResponse = require('twilio').twiml.VoiceResponse;23const response = new VoiceResponse();4const start = response.start();5start.stream({6name: 'Example Audio Stream',7url: 'wss://example.com/audiostream',8});9response.say('The stream has started.');1011console.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, it forks the audio stream of the Call. Twilio sends the audio in real-time over a WebSocket connection to the URL specified in the url attribute.
While Twilio is setting up the Media Stream, it immediately continues with the next TwiML instruction. If no instruction follows, the Call disconnects. Include a TwiML instruction after <Start><Stream> as shown in the example above.
The following is an example of <Connect><Stream>:
1const VoiceResponse = require('twilio').twiml.VoiceResponse;23const response = new VoiceResponse();4const connect = response.connect();5connect.stream({ url: 'wss://example.com/audiostream' });6response.say(7'This TwiML instruction is unreachable unless the Stream is ended by your WebSocket server.'8);910console.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 you use <Connect><Stream>, Twilio doesn't execute subsequent TwiML instructions. Twilio executes the remaining TwiML instructions only after your server closes the WebSocket connection.
<Stream> supports the following attributes:
| Attribute Name | Allowed Values | Default Value |
|---|---|---|
| url | A relative or absolute URL. | none |
| name | Optional. Unique name for the Stream. | none |
| track | Optional. inbound_track, outbound_track, both_tracks | inbound_track |
| statusCallback | Optional. An absolute URL. | none |
| statusCallbackMethod | Optional. GET or POST | POST |
The url attribute accepts either a relative or an absolute URL. On successful execution, Twilio establishes a wss WebSocket connection to the URL and begins streaming audio. 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 track. The naming of these tracks is from the Twilio platform perspective.
"Inbound" represents the audio Twilio receives from the other party on the Call. For example, this is 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 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 URL as a value. Whenever a Stream is started or stopped, Twilio sends an HTTP request to this URL with the following parameters:
| Parameter | Description |
|---|---|
AccountSid | The unique identifier of the Account responsible for this Stream. |
CallSid | The unique identifier of the Call. |
StreamSid | The unique identifier for this Stream. |
StreamName | If defined, this is the unique name of the Stream. Defaults to the StreamSid. |
StreamEvent | One of stream-started, stream-stopped, or stream-error (see StreamError for the message). |
StreamError | If an error has occurred, this will contain a detailed error message. |
Timestamp | The time of the event in ISO 8601 format. |
Specifies the HTTP method Twilio uses to request the statusCallback URL. Default: POST.
You can include additional key value pairs that Twilio passes to your WebSocket server. Use the nested <Parameter> TwiML noun to add custom parameters.
Note: The combined length of each <Parameter> name and value attributes must be under 500 characters.
1const VoiceResponse = require('twilio').twiml.VoiceResponse;23const response = new VoiceResponse();4const start = response.start();5const stream = start.stream({6url: 'wss://mystream.ngrok.io/example'7});8stream.parameter({9name: 'FirstName',10value: 'Jane'11});12stream.parameter({13name: 'LastName',14value: 'Doe'15});1617console.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 started with <Connect><Stream>) is to end the call. You can also update the call with TwiML instructions using the Update a Call resource.
The following sample TwiML instructions 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 following sample TwiML instructions:
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.