[Python] Twilio `<Stream>` Call Disconnects After 5 Seconds – No Error, Audio Not Played

Discussão em 'Python' iniciado por Stack, Julho 11, 2025.

  1. Stack

    Stack Membro Participativo

    I'm using Twilio's <Stream> tag to stream audio to a WebSocket for a voice call. The WebSocket is established successfully and I receive audio chunks from Twilio just fine. However:

    • The call disconnects after 5–6 seconds.
    • I'm sending μ-law encoded audio (8000Hz, 160 bytes per chunk) every 20ms.
    • My audio is not being played back to the caller.
    • Twilio doesn't return any error or log besides the <Start><Stream/></Start> and <Pause length="7"/>.

    Here’s a snippet of the audio payload I send (base64):


    {
    "event": "media",
    "streamSid": "FAKE_STREAM_SID_FOR_TEST",
    "media": {
    "payload": "////////fn5+Fo7/////fe5+..."
    }
    }

    Here is the code snippet for consume audio and send audio I have been using:

    @api.websocket("/twilio/wss/{call_id}")
    @tracer.start_as_current_span("twilio_wss_post")
    async def twilio_wss_post(call_id: str, websocket: WebSocket):
    stream_sid = None
    stop_event = asyncio.Event()
    call_state = await _db.call_get(call_id=UUID(call_id))

    if not hasattr(call_state, "audio_to_bot_queue"):
    object.__setattr__(call_state, "audio_to_bot_queue", asyncio.Queue())
    if not hasattr(call_state, "audio_from_bot_queue"):
    object.__setattr__(call_state, "audio_from_bot_queue", asyncio.Queue())

    await websocket.accept()

    async def _consume_audio():
    nonlocal stream_sid
    while True:
    msg = json.loads(await websocket.receive_text())
    if msg["event"] == "stop":
    stop_event.set()
    break
    if msg["event"] == "start":
    stream_sid = msg.get("streamSid")
    continue
    if msg["event"] != "media":
    continue
    chunk = msg["media"]["payload"]
    decoded = b64decode(chunk)
    await call_state.audio_to_bot_queue.put(decoded)

    async def _send_audio():
    CHUNK_SIZE = 160
    CHUNK_DELAY = 0.02
    timeout_start = time.time()

    while stream_sid is None:
    if time.time() - timeout_start > 10:
    return
    await asyncio.sleep(0.01)

    while not stop_event.is_set():
    try:
    audio = call_state.audio_from_bot_queue.get_nowait()
    except:
    audio = bytes([0xFF] * CHUNK_SIZE)

    for i in range(0, len(audio), CHUNK_SIZE):
    if stop_event.is_set():
    break
    chunk = audio[i:i + CHUNK_SIZE]
    if len(chunk) < CHUNK_SIZE:
    chunk += bytes([0xFF] * (CHUNK_SIZE - len(chunk)))
    await websocket.send_text(json.dumps({
    "event": "media",
    "streamSid": stream_sid,
    "media": {
    "payload": b64encode(chunk).decode("utf-8")
    }
    }))
    await asyncio.sleep(CHUNK_DELAY)

    await asyncio.gather(
    _consume_audio(),
    _send_audio()
    )

    I’ve validated:

    Sent audio plays perfectly locally.

    Received chunks from Twilio can be decoded and saved successfully.

    WebSocket logs show audio chunks being sent and received.

    Still, no audio is heard in the call and the call ends shortly after.

    What could be the reason Twilio is not playing back my audio? Could it be a formatting, timing, or stream issue?

    Any help appreciated!

    Continue reading...

Compartilhe esta Página