Media Streams provides a WebSocket connection to both sides of a phone call - receive audio and send audio back.
When a call comes in, Twilio hits your webhook. Respond with TwiML to start a stream:
app.post('/incoming', (req, res) => {
const twimlResponse = `<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Connect>
<Stream url="wss://${process.env.SERVER}/connection" />
</Connect>
</Response>`;
res.type('text/xml');
res.send(twimlResponse);
});
Handle the WebSocket connection for audio streaming:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ server });
wss.on('connection', (ws) => {
let streamSid = null;
ws.on('message', (message) => {
const msg = JSON.parse(message);
switch (msg.event) {
case 'start':
// Stream started, save the streamSid
streamSid = msg.start.streamSid;
break;
case 'media':
// Audio data from caller (base64 encoded mulaw)
const audio = msg.media.payload;
// Send to STT service
break;
case 'stop':
// Call ended
break;
}
});
});
Twilio sends/receives audio in a specific format:
| Property | Value |
|---|---|
| Encoding | mulaw (μ-law) |
| Sample rate | 8000 Hz |
| Channels | Mono |
| Format | Base64 encoded |
Send audio back to the caller:
function sendAudio(ws, streamSid, audioPayload) {
const message = {
event: 'media',
streamSid: streamSid,
media: {
payload: audioPayload // base64 encoded mulaw audio
}
};
ws.send(JSON.stringify(message));
}
Stop current playback (for interruption handling):
function clearAudio(ws, streamSid) {
const message = {
event: 'clear',
streamSid: streamSid
};
ws.send(JSON.stringify(message));
}
| Event | Direction | Description |
|---|---|---|
connected | Twilio → App | WebSocket connected |
start | Twilio → App | Stream started, contains streamSid |
media | Both | Audio data (base64 mulaw) |
stop | Twilio → App | Stream ended |
clear | App → Twilio | Clear audio buffer |
mark | App → Twilio | Mark position in audio stream |
Using Twilio CLI:
twilio phone-numbers:update +1XXXXXXXXXX \
--voice-url=https://your-server.com/incoming
Or configure in Twilio Console.