fix(workflow): track fixed speech at transport output

This commit is contained in:
Xin Wang
2026-08-06 10:21:36 +08:00
parent 5cb13a3cac
commit aaca128f82
6 changed files with 384 additions and 46 deletions
+55 -3
View File
@@ -14,15 +14,67 @@ from pipecat.transports.base_transport import TransportParams
# WebRTC
from pipecat.transports.smallwebrtc.connection import SmallWebRTCConnection
from pipecat.transports.smallwebrtc.transport import SmallWebRTCTransport
from pipecat.transports.smallwebrtc.transport import (
SmallWebRTCOutputTransport,
SmallWebRTCTransport,
)
# 裸 WS 音频流
from pipecat.transports.websocket.fastapi import (
FastAPIWebsocketOutputTransport,
FastAPIWebsocketTransport,
FastAPIWebsocketParams,
)
from pipecat.serializers.protobuf import ProtobufFrameSerializer
from services.pipecat.call_lifecycle import FixedSpeechPlaybackMarkerFrame
class _PlaybackMarkerOutputMixin:
"""Resolve fixed-speech markers after preceding audio has been sent."""
async def write_transport_frame(self, frame):
if isinstance(frame, FixedSpeechPlaybackMarkerFrame):
await frame.completion.mark_played()
return
await super().write_transport_frame(frame)
class _WebRTCOutputTransport(
_PlaybackMarkerOutputMixin,
SmallWebRTCOutputTransport,
):
pass
class _WebRTCTransport(SmallWebRTCTransport):
def output(self) -> SmallWebRTCOutputTransport:
if not self._output:
self._output = _WebRTCOutputTransport(
self._client,
self._params,
name=self._input_name,
)
return self._output
class _WebsocketOutputTransport(
_PlaybackMarkerOutputMixin,
FastAPIWebsocketOutputTransport,
):
pass
class _WebsocketTransport(FastAPIWebsocketTransport):
def __init__(self, websocket: WebSocket, params: FastAPIWebsocketParams):
super().__init__(websocket=websocket, params=params)
self._output = _WebsocketOutputTransport(
self,
self._client,
self._params,
name=self._output_name,
)
def _base_params(*, video_in_enabled: bool = False) -> dict:
"""两种 transport 共享的音频参数。"""
@@ -41,7 +93,7 @@ def build_webrtc_transport(
*,
video_in_enabled: bool = False,
) -> SmallWebRTCTransport:
return SmallWebRTCTransport(
return _WebRTCTransport(
webrtc_connection=connection,
params=TransportParams(**_base_params(video_in_enabled=video_in_enabled)),
)
@@ -51,7 +103,7 @@ def build_ws_transport(websocket: WebSocket) -> FastAPIWebsocketTransport:
"""裸 WS 输出。序列化用 protobuf(自定义客户端用同款解码);
若对接电话商,把 serializer 换成对应的 TwilioFrameSerializer 等即可。
"""
return FastAPIWebsocketTransport(
return _WebsocketTransport(
websocket=websocket,
params=FastAPIWebsocketParams(
serializer=ProtobufFrameSerializer(),