mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-06-07 07:55:16 +02:00
fix: honor telnyxs per-call codec in bidirectional stream
Telnyx's bidirectional stream uses different codecs per direction:
- Dograh → Telnyx: what we declare via `stream_bidirectional_codec`
- Telnyx → Dograh: whatever the PSTN leg negotiated (PCMA for UK,
Europe, India termination; PCMU for US), announced as
`media_format.encoding` on the WebSocket start message.
We hardcoded both directions on the serializer to PCMU, so any call
whose PSTN leg used PCMA arrived as A-law bytes that we decoded
through a μ-law table → static for the entire call.
`handle_websocket` now extracts `media_format.encoding` from the
start message and threads it through `transport_kwargs`. The
serializer uses it for the Telnyx → Dograh direction; the
Dograh → Telnyx direction stays pinned to PCMU to match the
unchanged `stream_bidirectional_codec` in the dial/answer payloads.
Note: pipecat's `TelnyxFrameSerializer` names its params from the
call's POV, not Dograh's — `inbound_encoding` is what we send into
the call, `outbound_encoding` is what we receive. Easy to mix up.
This commit is contained in:
parent
983b9bee71
commit
5ee68f58bb
2 changed files with 17 additions and 4 deletions
|
|
@ -82,6 +82,9 @@ class TelnyxProvider(TelephonyProvider):
|
|||
f"{backend_endpoint}/api/v1/telephony/telnyx/events/{workflow_run_id}"
|
||||
)
|
||||
|
||||
# stream_bidirectional_codec controls only the Dograh → Telnyx direction.
|
||||
# The Telnyx → Dograh direction follows the PSTN leg and is announced via
|
||||
# media_format.encoding in the WebSocket start message.
|
||||
payload = {
|
||||
"connection_id": self.connection_id,
|
||||
"to": to_number,
|
||||
|
|
@ -268,11 +271,15 @@ class TelnyxProvider(TelephonyProvider):
|
|||
await websocket.close(code=4400, reason="Expected start event")
|
||||
return
|
||||
|
||||
# Extract Telnyx-specific identifiers
|
||||
# media_format.encoding is the codec Telnyx delivers on the
|
||||
# inbound direction (Telnyx → Dograh); the outbound direction is
|
||||
# pinned to PCMU separately via stream_bidirectional_codec.
|
||||
try:
|
||||
stream_id = start_data.get("stream_id", "")
|
||||
start_info = start_data.get("start", {})
|
||||
call_control_id = start_info.get("call_control_id", "")
|
||||
media_format = start_info.get("media_format") or {}
|
||||
encoding = media_format.get("encoding") or "PCMU"
|
||||
except (KeyError, AttributeError):
|
||||
logger.error("Missing stream_id or call_control_id in start message")
|
||||
await websocket.close(code=4400, reason="Missing stream identifiers")
|
||||
|
|
@ -288,7 +295,7 @@ class TelnyxProvider(TelephonyProvider):
|
|||
|
||||
logger.info(
|
||||
f"Telnyx stream started: stream_id={stream_id}, "
|
||||
f"call_control_id={call_control_id}"
|
||||
f"call_control_id={call_control_id}, encoding={encoding}"
|
||||
)
|
||||
|
||||
await run_pipeline_telephony(
|
||||
|
|
@ -301,6 +308,7 @@ class TelnyxProvider(TelephonyProvider):
|
|||
transport_kwargs={
|
||||
"stream_id": stream_id,
|
||||
"call_control_id": call_control_id,
|
||||
"encoding": encoding,
|
||||
},
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ async def create_transport(
|
|||
telephony_configuration_id: int | None = None,
|
||||
stream_id: str,
|
||||
call_control_id: str,
|
||||
encoding: str = "PCMU",
|
||||
):
|
||||
"""Create a transport for Telnyx connections."""
|
||||
config = await load_credentials_for_transport(
|
||||
|
|
@ -36,12 +37,16 @@ async def create_transport(
|
|||
f"Incomplete Telnyx configuration for organization {organization_id}"
|
||||
)
|
||||
|
||||
# Pipecat's TelnyxFrameSerializer names its params from the call's POV,
|
||||
# not Dograh's: ``inbound_encoding`` is what we *send into the call*
|
||||
# (Dograh → Telnyx), and ``outbound_encoding`` is what we *receive out of
|
||||
# the call* (Telnyx → Dograh).
|
||||
serializer = TelnyxFrameSerializer(
|
||||
stream_id=stream_id,
|
||||
call_control_id=call_control_id,
|
||||
api_key=api_key,
|
||||
outbound_encoding="PCMU",
|
||||
inbound_encoding="PCMU",
|
||||
inbound_encoding="PCMU", # Dograh → Telnyx; matches stream_bidirectional_codec
|
||||
outbound_encoding=encoding, # Telnyx → Dograh; from media_format.encoding
|
||||
)
|
||||
|
||||
mixer = await build_audio_out_mixer(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue