Recipes← all recipesView on GitHub

Stream call audio to your own server

Voicemedia streaming and audio forking

Copy live call audio to your WebSocket or RTP server, then stop the stream by its control ID.

media-streaming

The claim

The bundled schema describes tap’s uri as the “destination of the tap media stream: rtp://IP:port, ws://example.com, or wss://example.com”. direction is speak “for what party says”, listen “for what party hears”, or both. codec is PCMU or PCMA. control_id is the “identifier for this tap to use with stop_tap”. The bundled schema requires only uri. The vendored REST spec has the same operation as the call command calling.tap. It takes a tap configuration of type audio and a device of type ws or rtp, and calling.tap.stop ends it. The SDK wraps those as client.calling.tap and client.calling.tap_stop.

How it works

- answer: {}
- tap:
    uri: "wss://media.example.com/tap"
    control_id: "workshop-tap"
    direction: "both"
    codec: "PCMU"
- connect:
    to: "+15550100001"
    timeout: 20
- stop_tap:
    control_id: "workshop-tap"
- hangup: {}

The document carries tap for both directions, then connect, then stop_tap with the same control id. The Python surface builds the same document with SWMLService and adds the REST pair:

def start_tap(call_id):
    return client.calling.tap(call_id, control_id=CONTROL_ID,
                              tap={"type": "audio", "params": {"direction": "both"}},
                              device={"type": "ws", "params": {"uri": TAP_URI}})

def stop_tap(call_id):
    return client.calling.tap_stop(call_id, control_id=CONTROL_ID)

What the platform receives from start_tap:

{"command": "calling.tap", "id": "6d3f4a0e-2b1c-4e7a-9f0d-1c2b3a4d5e6f",
 "params": {"control_id": "workshop-tap",
            "tap": {"type": "audio", "params": {"direction": "both"}},
            "device": {"type": "ws", "params": {"uri": "wss://media.example.com/tap"}}}}

The spec describes the RTP device’s addr as a “public IPv4 address” and says “private/reserved ranges are rejected”. It says the WebSocket uri “must start with ws:// or wss://”.

Limitations

You prove the documents and the requests. What arrives on your socket, and in what framing, is the platform’s side of a live call and belongs to the tap documentation.

What to change first

Change direction to speak in both surfaces and run the verifier. The tap equality fails, which is the point: speak, listen and both are the three choices, and the document names one.