TwiMLemoji Voice: <Stream>
La instrucción <Stream>
te permite recibir transmisiones de audio sin procesar de una llamada telefónica en vivo mediante WebSockets casi en tiempo real.
El uso más básico de <Stream>:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Start>
<Stream url="wss://mystream.ngrok.io/audiostream" />
</Start>
</Response>
Este TwiML instruirá a Twilio para que bifurque la transmisión de audio de la llamada actual y lo envíe en tiempo real mediante WebSocket a wss://mystream.ngrok.io/audiostream.
El verbo <Start>
inicia el <Stream>
de audio de forma asincrónica y de forma inmediata continúa con la siguiente instrucción TwiML. Si no hay ninguna instrucción, la llamada se desconectará. Para evitar esto, proporciona una instrucción TwiML a fin de continuar la llamada.
Si prefieres una transmisión bidireccional sincrónica, debes utilizar el verbo <Connect>
.
Existe una asignación de uno a uno de una transmisión a una conexión WebSocket, por lo que habrá como máximo una llamada que se transmitirá mediante una única conexión WebSocket. Se proporcionarán metadatos para que puedas gestionar varias conexiones entrantes y gestionar las asignaciones entre el identificador de transmisión único o StreamSid
.
Si se encuentran problemas de comunicación con tu servidor WebSocket, se informará de ellos en el depurador de Twilio con información adicional sobre el error.
Hay un máximo de cuatro transmisiones bifurcadas permitidas por llamada. Cada pista, sea inbound
o outbound
, es una transmisión bifurcada.
Atributos
<Stream>
admite los siguientes atributos:
Nombre de atributo | Valores permitidos | Valor predeterminado |
---|---|---|
url | URL relativa o absoluta | ninguno |
name | Opcional. Nombre único para la transmisión | ninguno |
track | Opcional. inbound_track , outbound_track , both_tracks |
inbound_track |
statusCallback | Opcional. URL relativa o absoluta | ninguno |
statusCallbackMethod | Opcional. GET or POST |
POST |
url
El atributo url
acepta una URL relativa o absoluta. Si la ejecución se realiza de forma correcta, se establecerá una conexión de WebSocket a la dirección URL y se iniciará la transmisión de audio. wss
es el único protocolo soportado.
La url
no admite parámetros de cadena de consulta. Para pasar pares clave-valor personalizados al WebSocket, utiliza parámetros personalizados en su lugar.
name
Proporcionar un atributo name
(nombre) te permitirá hacer referencia a la transmisión de forma directa. Este nombre debe ser único por llamada. Por ejemplo, detener una transmisión por nombre.
track
El atributo track
te permite solicitar de forma opcional recibir una pista específica de una llamada. En cualquier llamada activa dada, hay pistas entrantes y salientes. Las pistas entrantes representan el audio que Twilio recibe de la llamada y las salientes representan el audio generado por Twilio que se reproduce en la llamada.
Por defecto, Twilio siempre transmite la pista entrante de una llamada. Cuando se inicia una transmisión usando el verbo bidireccional sincrónico <Connect>
, esta es tu única opción.
Sin embargo, si estás usando una transmisión asincrónica mediante el verbo <Start>
, puedes solicitar el audio que genera con outbound_track
. Para recibir ambas pistas de una llamada utiliza both_tracks
. Si se utiliza both_tracks
, recibirás tanto el evento de medios entrante como el evento de medios saliente.
statusCallback
El atributo statusCallback
toma como valor una URL absoluta o relativa. Cada vez que se inicia o se detiene una transmisión, Twilio hará una solicitud a esta URL con los siguientes parámetros:
Parámetro | Descripción |
---|---|
AccountSid | Identificador exclusivo de la cuenta responsable de esta transmisión. |
CallSid | El identificador único de la llamada |
StreamSid | El identificador único de esta transmisión |
StreamName | Si se establece, este es el nombre único de la transmisión. El valor predeterminado es StreamSid |
StreamEvent | Puede ser stream-started , stream-stopped o stream-error (consulta StreamError para ver el mensaje) |
StreamError | Si se ha producido un error, contendrá un mensaje de error detallado. |
Timestamp | La hora del evento en formato ISO 8601 |
statusCallbackMethod
El método HTTP que se va a utilizar cuando se solicita la URL statusCallback
. El valor predeterminado es POST
.
Parámetros personalizados
Es posible incluir pares clave-valor adicionales que se pasarán junto con tu transmisión. Para hacer esto, usa el sustantivo TwiML anidado <Parameter>
.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Start>
<Stream url="wss://mystream.ngrok.io/example" >
<Parameter name="FirstName" value ="Jane"/>
<Parameter name="LastName" value ="Doe" />
<Parameter name="RemoteParty" value ="Bob" />
</Stream>
</Start>
</Response>
Estos valores se enviarán junto con el mensaje Iniciar WebSocket.
En la actualidad, la cantidad de datos que se pueden enviar desde parámetros personalizados tiene una limitación de tamaño. Intenta mantener la cantidad total de caracteres de tus parámetros (tanto name
como value
) por debajo de 500 caracteres.
Detener una transmisión
Es posible detener una transmisión asincrónica con name. Por ejemplo, denominando Stream
my_first_stream
.
<Start>
<Stream name="my_first_stream" url="wss://mystream.ngrok.io/audiostream" />
</Start>
Puedes usar más adelante el name
único de my_first_stream
para detener la transmisión.
<Stop>
<Stream name="my_first_stream" />
</Stop>
Mensajes de WebSocket: de Twilio
Existen distintos tipos de eventos que ocurren durante el ciclo de vida de la transmisión. Estos eventos se representan mediante mensajes de WebSocket: Conectado, Iniciar, Medios, Detener, y la función solo bidireccional Marcar.
Cada mensaje enviado es una cadena JSON. Para determinar qué tipo de evento está ocurriendo, utiliza la propiedad event
de cada objeto JSON.
Twilio envía los siguientes mensajes a tu aplicación:
Mensaje conectado
El primer mensaje enviado una vez establecida una conexión con WebSocket es el evento Connected
. Este mensaje describe el protocolo que se espera en los mensajes siguientes.
Parámetro | Descripción |
---|---|
event | El valor de connected |
protocol | Define el protocolo para la duración de las conexiones de WebSocket. Por ejemplo: "Call" |
version | Versión semántica del protocolo. |
Ejemplo de mensaje conectado
{
"event": "connected",
"protocol": "Call",
"version": "1.0.0"
}
Mensaje de inicio
Este mensaje contiene metadatos importantes sobre la transmisión y se envía de inmediato después del mensaje Connected
(Conectado). Solo se envía una vez al inicio de la transmisión.
Parámetro | Descripción |
---|---|
event | El valor de start |
sequenceNumber | Número utilizado para realizar un seguimiento del orden de envío de mensajes. El primer mensaje comienza con "1" y, luego, se incrementa. |
start | Un objeto que contiene metadatos de la transmisión |
start.streamSid | El identificador único de la transmisión |
start.accountSid | El identificador de cuenta que creó la transmisión |
start.callSid | El identificador de llamada desde donde se inició la transmisión. |
start.tracks | Una arreglo de valores esto indica qué flujos de medios se esperan en los mensajes posteriores. Los valores incluyen inbound y outbound . |
start.customParameters | Un objeto que representa los Parámetros personalizados que se establecieron cuando se definió la transmisión |
start.mediaFormat | Un objeto que contiene el formato de la carga útil en los mensajes multimedia. |
start.mediaFormat.encoding | La codificación de los datos en la carga útil siguiente. El valor siempre será audio/x-mulaw . |
start.mediaFormat.sampleRate | La velocidad de muestreo en hercios de los datos de audio próximos. El valor es siempre 8000 |
start.mediaFormat.channels | La cantidad de canales en los datos de audio de entrada. El valor siempre será 1 |
streamSid | El identificador único de la transmisión |
Ejemplo de mensaje de inicio
{
"event": "start",
"sequenceNumber": "2",
"start": {
"streamSid": "MZ18ad3ab5a668481ce02b83e7395059f0",
"accountSid": "AC123",
"callSid": "CA123",
"tracks": [
"inbound",
"outbound"
],
"customParameters": {
"FirstName": "Jane",
"LastName": "Doe",
"RemoteParty": "Bob",
},
"mediaFormat": {
"encoding": "audio/x-mulaw",
"sampleRate": 8000,
"channels": 1
}
},
"streamSid": "MZ18ad3ab5a668481ce02b83e7395059f0"
}
Mensaje de medios
Este tipo de mensaje encapsula los datos de audio sin procesar.
Parámetro | Descripción |
---|---|
event | El valor de media |
sequenceNumber | Número utilizado para realizar un seguimiento del orden de envío de mensajes. El primer mensaje comienza con "1" y, luego, se incrementa para cada mensaje. |
media | Un objeto que contiene metadatos de medios y carga útil |
media.track | Puede ser inbound o outbound |
media.chunk | El fragmento del mensaje. El primer mensaje comenzará con "1" y se incrementará con cada mensaje subsiguiente. |
media.timestamp | Presentación de la marca de tiempo en milisegundos desde el inicio de la transmisión. |
media.payload | Audio sin procesar en codificado en base64 |
streamSid | El identificador único de la transmisión |
Ejemplo de mensajes de medios
Pista saliente
{
"event": "media",
"sequenceNumber": "3",
"media": {
"track": "outbound",
"chunk": "1",
"timestamp": "5",
"payload": "no+JhoaJjpzSHxAKBgYJDhtEopGKh4aIjZm7JhILBwYIDRg1qZSLh4aIjJevLBUMBwYHDBUsr5eMiIaHi5SpNRgNCAYHCxImu5mNiIaHipGiRBsOCQYGChAf0pyOiYaGiY+e/x4PCQYGCQ4cUp+QioaGiY6bxCIRCgcGCA0ZO6aSi4eGiI2YtSkUCwcGCAwXL6yVjIeGh4yVrC8XDAgGBwsUKbWYjYiGh4uSpjsZDQgGBwoRIsSbjomGhoqQn1IcDgkGBgkPHv+ej4mGhomOnNIfEAoGBgkOG0SikYqHhoiNmbsmEgsHBggNGDWplIuHhoiMl68sFQwHBgcMFSyvl4yIhoeLlKk1GA0IBgcLEia7mY2IhoeKkaJEGw4JBgYKEB/SnI6JhoaJj57/Hg8JBgYJDhxSn5CKhoaJjpvEIhEKBwYIDRk7ppKLh4aIjZi1KRQLBwYIDBcvrJWMh4aHjJWsLxcMCAYHCxQptZiNiIaHi5KmOxkNCAYHChEixJuOiYaGipCfUhwOCQYGCQ8e/56PiYaGiY6c0h8QCgYGCQ4bRKKRioeGiI2ZuyYSCwcGCA0YNamUi4eGiIyXrywVDAcGBwwVLK+XjIiGh4uUqTUYDQgGBwsSJruZjYiGh4qRokQbDgkGBgoQH9KcjomGhomPnv8eDwkGBgkOHFKfkIqGhomOm8QiEQoHBggNGTumkouHhoiNmLUpFAsHBggMFy+slYyHhoeMlawvFwwIBgcLFCm1mI2IhoeLkqY7GQ0IBgcKESLEm46JhoaKkJ9SHA4JBgYJDx7/no+JhoaJjpzSHxAKBgYJDhtEopGKh4aIjZm7JhILBwYIDRg1qZSLh4aIjJevLBUMBwYHDBUsr5eMiIaHi5SpNRgNCAYHCxImu5mNiIaHipGiRBsOCQYGChAf0pyOiYaGiY+e/x4PCQYGCQ4cUp+QioaGiY6bxCIRCgcGCA0ZO6aSi4eGiI2YtSkUCwcGCAwXL6yVjIeGh4yVrC8XDAgGBwsUKbWYjYiGh4uSpjsZDQgGBwoRIsSbjomGhoqQn1IcDgkGBgkPHv+ej4mGhomOnNIfEAoGBgkOG0SikYqHhoiNmbsmEgsHBggNGDWplIuHhoiMl68sFQwHBgcMFSyvl4yIhoeLlKk1GA0IBgcLEia7mY2IhoeKkaJEGw4JBgYKEB/SnI6JhoaJj57/Hg8JBgYJDhxSn5CKhoaJjpvEIhEKBwYIDRk7ppKLh4aIjZi1KRQLBwYIDBcvrJWMh4aHjJWsLxcMCAYHCxQptZiNiIaHi5KmOxkNCAYHChEixJuOiYaGipCfUhwOCQYGCQ8e/56PiYaGiY6c0h8QCgYGCQ4bRKKRioeGiA=="
} ,
"streamSid": "MZ18ad3ab5a668481ce02b83e7395059f0"
}
Pista entrante
{
"event": "media",
"sequenceNumber": "4",
"media": {
"track": "inbound",
"chunk": "2",
"timestamp": "5",
"payload": "no+JhoaJjpzSHxAKBgYJDhtEopGKh4aIjZm7JhILBwYIDRg1qZSLh4aIjJevLBUMBwYHDBUsr5eMiIaHi5SpNRgNCAYHCxImu5mNiIaHipGiRBsOCQYGChAf0pyOiYaGiY+e/x4PCQYGCQ4cUp+QioaGiY6bxCIRCgcGCA0ZO6aSi4eGiI2YtSkUCwcGCAwXL6yVjIeGh4yVrC8XDAgGBwsUKbWYjYiGh4uSpjsZDQgGBwoRIsSbjomGhoqQn1IcDgkGBgkPHv+ej4mGhomOnNIfEAoGBgkOG0SikYqHhoiNmbsmEgsHBggNGDWplIuHhoiMl68sFQwHBgcMFSyvl4yIhoeLlKk1GA0IBgcLEia7mY2IhoeKkaJEGw4JBgYKEB/SnI6JhoaJj57/Hg8JBgYJDhxSn5CKhoaJjpvEIhEKBwYIDRk7ppKLh4aIjZi1KRQLBwYIDBcvrJWMh4aHjJWsLxcMCAYHCxQptZiNiIaHi5KmOxkNCAYHChEixJuOiYaGipCfUhwOCQYGCQ8e/56PiYaGiY6c0h8QCgYGCQ4bRKKRioeGiI2ZuyYSCwcGCA0YNamUi4eGiIyXrywVDAcGBwwVLK+XjIiGh4uUqTUYDQgGBwsSJruZjYiGh4qRokQbDgkGBgoQH9KcjomGhomPnv8eDwkGBgkOHFKfkIqGhomOm8QiEQoHBggNGTumkouHhoiNmLUpFAsHBggMFy+slYyHhoeMlawvFwwIBgcLFCm1mI2IhoeLkqY7GQ0IBgcKESLEm46JhoaKkJ9SHA4JBgYJDx7/no+JhoaJjpzSHxAKBgYJDhtEopGKh4aIjZm7JhILBwYIDRg1qZSLh4aIjJevLBUMBwYHDBUsr5eMiIaHi5SpNRgNCAYHCxImu5mNiIaHipGiRBsOCQYGChAf0pyOiYaGiY+e/x4PCQYGCQ4cUp+QioaGiY6bxCIRCgcGCA0ZO6aSi4eGiI2YtSkUCwcGCAwXL6yVjIeGh4yVrC8XDAgGBwsUKbWYjYiGh4uSpjsZDQgGBwoRIsSbjomGhoqQn1IcDgkGBgkPHv+ej4mGhomOnNIfEAoGBgkOG0SikYqHhoiNmbsmEgsHBggNGDWplIuHhoiMl68sFQwHBgcMFSyvl4yIhoeLlKk1GA0IBgcLEia7mY2IhoeKkaJEGw4JBgYKEB/SnI6JhoaJj57/Hg8JBgYJDhxSn5CKhoaJjpvEIhEKBwYIDRk7ppKLh4aIjZi1KRQLBwYIDBcvrJWMh4aHjJWsLxcMCAYHCxQptZiNiIaHi5KmOxkNCAYHChEixJuOiYaGipCfUhwOCQYGCQ8e/56PiYaGiY6c0h8QCgYGCQ4bRKKRioeGiA=="
},
"streamSid": "MZ18ad3ab5a668481ce02b83e7395059f0"
}
Mensaje de detención
Se enviará un mensaje de detención cuando la transmisión utilice <Stop>
o la llamada haya finalizado.
Parámetro | Descripción |
---|---|
event | El valor de stop |
sequenceNumber | Número utilizado para realizar un seguimiento del orden de envío de mensajes. El primer mensaje comienza con "1" y, luego, se incrementa para cada mensaje. |
stop | Un objeto que contiene metadatos de la transmisión |
stop.accountSid | El identificador de cuenta que creó la transmisión |
stop.callSid | El identificador de llamada que inició la transmisión |
streamSid | El identificador único de la transmisión |
Ejemplo de mensaje de detención
{
"event": "stop",
"sequenceNumber": "5",
"stop": {
"accountSid": "AC123",
"callSid": "CA123"
},
"streamSid": "MZ18ad3ab5a668481ce02b83e7395059f0"
}
Mensaje de marca
El evento mark
se envía solo durante la transmisión bidireccional usando el verbo <Connect>
. Se utiliza para realizar un seguimiento, o etiquetar, cuando el medio se ha completado.
Parámetro | Descripción |
---|---|
event | El valor de mark |
sequenceNumber | Número utilizado para realizar un seguimiento del orden de envío de mensajes. El primer mensaje comienza con "1" y, luego, se incrementa para cada mensaje. |
mark | Un objeto que contiene los metadatos de la marca |
mark.name | El valor especificado cuando se crea un mensaje mark a Twilio |
Ejemplo de mensaje de marca
{
"event": "mark",
"sequenceNumber": "4",
"streamSid": "MZ18ad3ab5a668481ce02b83e7395059f0",
"mark": {
"name": "my label"
}
}
Mensajes de WebSocket: a Twilio
Los eventos que puedes enviar a Twilio son Medios, Marca, y Limpieza.
Para enviar datos de vuelta a Twilio, tu transmisión se debe haber iniciado con el verbo <Connect> de TwiML. Esto te dará una transmisión bidireccional que te permite canalizar audio y controlar el flujo.
Mensaje de medios
Para enviar medios de nuevo a Twilio, debes proporcionar un mensaje media
con formato similar. La carga útil debe estar codificada en audio/x-mulaw
con una velocidad de muestreo de 8000 y codificada en base64. El audio puede ser de cualquier tamaño.
Los mensajes de medios se almacenarán y reproducirán en el orden en que se reciban. Si deseas interrumpir el audio almacenado, consulta el mensaje de evento `clear'.
La carga de medios no debe contener bytes de encabezado de tipo de archivo de audio. Si se proporcionan bytes de encabezado, el contenido de medios se transmitirá de forma incorrecta.
Parámetro | Descripción |
---|---|
event | El valor de media |
streamSid | El SID del Stream que debería reproducir el audio |
media | Un objeto que contiene metadatos de medios y carga útil |
media.payload | Audio sin procesar mulaw/8000 en codificado en base64 |
{
"event": "media",
"streamSid": "MZ18ad3ab5a668481ce02b83e7395059f0",
"media": {
"payload": "a3242sadfasfa423242... (a base64 encoded string of 8000/mulaw)"
}
}
Mensaje de marca
Enviar un mensaje de evento mark
después de enviar un mensaje de evento media
para recibir una notificación cuando el audio que has enviado se haya completado. Recibirás un evento mark
con un name
coincidente de Twilio cuando el audio termine (o si no hay audio almacenado).
También recibirás un mensaje del evento mark
entrante si el búfer se borró usando el mensaje de evento clear
.
Parámetro | Descripción |
---|---|
event | El valor de mark |
streamSid | El SID de la transmisión que debería recibir la marca |
mark | Un objeto que contiene metadatos de marca y carga útil |
mark.name | Un nombre específico de tus necesidades que te ayudará a reconocer el evento de mark futuro |
Ejemplo Mensaje de marca
{
"event": "mark",
"streamSid": "MZ18ad3ab5a668481ce02b83e7395059f0",
"mark": {
"name": "my label"
}
}
Mensaje de limpieza
Envía el mensaje de evento clear
si deseas interrumpir el audio que ha enviado varios mensajes de evento media
. Esto vaciará todo el audio almacenado y hará que cualquier mensaje de evento mark
se envíe de vuelta a ti.
Parámetro | Descripción |
---|---|
event | El valor de clear |
streamSid | El SID de la transmisión que debería recibir la marca |
Ejemplo de mensaje de limpieza
{
"event": "clear",
"streamSid": "MZ18ad3ab5a668481ce02b83e7395059f0",
}
Ejemplos
Inicia un nuevo MediaStream asincrónico llamado "Example Audio Stream"
(Transmisión de audio de ejemplo). La transmisión comenzará a enviar mensajes a la url
especificada mediante una conexión de WebSocket.
Puedes enviar información personalizada adicional usando el sustantivo de TwiML <Parameter>
. Estos valores se entregarán en el mensaje Iniciar WebSocket en la sección customParameters
.
Transmisiones de medios bidireccionales
Si deseas devolver medios a la llamada, la transmisión *debe* ser bidireccional. Para ello, inicia la transmisión utilizando el verbo <Connect> de TwiML en lugar del verbo <Start>. El atributo url
del sustantivo <Stream> debe establecerse en un servidor de WebSockets seguro (wss).
Servidores de medios
Los medios de transmisión deben comunicarse con la nube de Twilio para poder funcionar. A continuación, se enumeran los rangos de direcciones IP utilizados para comunicarse con la nube de Twilio. Si es necesario, usa esta información para configurar tu servidor de seguridad a fin de permitir la comunicación con Twilio.
Edge | Location | Server IP Address Range |
---|---|---|
ashburn | US East Coast (Virginia) | 34.203.254.0/24 3.235.111.128/25 |
Traffic is secure web socket over TCP
¿Necesitas ayuda?
Todos la necesitamos a veces; la programación es difícil. Obtén ayuda ahora de nuestro equipo de soporte, o recurre a la sabiduría de la multitud visitando Stack Overflow Collective de Twilio o navegando por la etiqueta de Twilio en Stack Overflow.