dv-pipecat-ai 0.0.74.dev770__py3-none-any.whl → 0.0.82.dev776__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dv-pipecat-ai might be problematic. Click here for more details.
- {dv_pipecat_ai-0.0.74.dev770.dist-info → dv_pipecat_ai-0.0.82.dev776.dist-info}/METADATA +137 -93
- dv_pipecat_ai-0.0.82.dev776.dist-info/RECORD +340 -0
- pipecat/__init__.py +17 -0
- pipecat/adapters/base_llm_adapter.py +36 -1
- pipecat/adapters/schemas/direct_function.py +296 -0
- pipecat/adapters/schemas/function_schema.py +15 -6
- pipecat/adapters/schemas/tools_schema.py +55 -7
- pipecat/adapters/services/anthropic_adapter.py +22 -3
- pipecat/adapters/services/aws_nova_sonic_adapter.py +23 -3
- pipecat/adapters/services/bedrock_adapter.py +22 -3
- pipecat/adapters/services/gemini_adapter.py +16 -3
- pipecat/adapters/services/open_ai_adapter.py +17 -2
- pipecat/adapters/services/open_ai_realtime_adapter.py +23 -3
- pipecat/audio/filters/base_audio_filter.py +30 -6
- pipecat/audio/filters/koala_filter.py +37 -2
- pipecat/audio/filters/krisp_filter.py +59 -6
- pipecat/audio/filters/noisereduce_filter.py +37 -0
- pipecat/audio/interruptions/base_interruption_strategy.py +25 -5
- pipecat/audio/interruptions/min_words_interruption_strategy.py +21 -4
- pipecat/audio/mixers/base_audio_mixer.py +30 -7
- pipecat/audio/mixers/soundfile_mixer.py +53 -6
- pipecat/audio/resamplers/base_audio_resampler.py +17 -9
- pipecat/audio/resamplers/resampy_resampler.py +26 -1
- pipecat/audio/resamplers/soxr_resampler.py +32 -1
- pipecat/audio/resamplers/soxr_stream_resampler.py +101 -0
- pipecat/audio/utils.py +194 -1
- pipecat/audio/vad/silero.py +60 -3
- pipecat/audio/vad/vad_analyzer.py +114 -30
- pipecat/clocks/base_clock.py +19 -0
- pipecat/clocks/system_clock.py +25 -0
- pipecat/extensions/voicemail/__init__.py +0 -0
- pipecat/extensions/voicemail/voicemail_detector.py +707 -0
- pipecat/frames/frames.py +590 -156
- pipecat/metrics/metrics.py +64 -1
- pipecat/observers/base_observer.py +58 -19
- pipecat/observers/loggers/debug_log_observer.py +56 -64
- pipecat/observers/loggers/llm_log_observer.py +8 -1
- pipecat/observers/loggers/transcription_log_observer.py +19 -7
- pipecat/observers/loggers/user_bot_latency_log_observer.py +32 -5
- pipecat/observers/turn_tracking_observer.py +26 -1
- pipecat/pipeline/base_pipeline.py +5 -7
- pipecat/pipeline/base_task.py +52 -9
- pipecat/pipeline/parallel_pipeline.py +121 -177
- pipecat/pipeline/pipeline.py +129 -20
- pipecat/pipeline/runner.py +50 -1
- pipecat/pipeline/sync_parallel_pipeline.py +132 -32
- pipecat/pipeline/task.py +263 -280
- pipecat/pipeline/task_observer.py +85 -34
- pipecat/pipeline/to_be_updated/merge_pipeline.py +32 -2
- pipecat/processors/aggregators/dtmf_aggregator.py +29 -22
- pipecat/processors/aggregators/gated.py +25 -24
- pipecat/processors/aggregators/gated_openai_llm_context.py +22 -2
- pipecat/processors/aggregators/llm_response.py +398 -89
- pipecat/processors/aggregators/openai_llm_context.py +161 -13
- pipecat/processors/aggregators/sentence.py +25 -14
- pipecat/processors/aggregators/user_response.py +28 -3
- pipecat/processors/aggregators/vision_image_frame.py +24 -14
- pipecat/processors/async_generator.py +28 -0
- pipecat/processors/audio/audio_buffer_processor.py +78 -37
- pipecat/processors/consumer_processor.py +25 -6
- pipecat/processors/filters/frame_filter.py +23 -0
- pipecat/processors/filters/function_filter.py +30 -0
- pipecat/processors/filters/identity_filter.py +17 -2
- pipecat/processors/filters/null_filter.py +24 -1
- pipecat/processors/filters/stt_mute_filter.py +56 -21
- pipecat/processors/filters/wake_check_filter.py +46 -3
- pipecat/processors/filters/wake_notifier_filter.py +21 -3
- pipecat/processors/frame_processor.py +488 -131
- pipecat/processors/frameworks/langchain.py +38 -3
- pipecat/processors/frameworks/rtvi.py +719 -34
- pipecat/processors/gstreamer/pipeline_source.py +41 -0
- pipecat/processors/idle_frame_processor.py +26 -3
- pipecat/processors/logger.py +23 -0
- pipecat/processors/metrics/frame_processor_metrics.py +77 -4
- pipecat/processors/metrics/sentry.py +42 -4
- pipecat/processors/producer_processor.py +34 -14
- pipecat/processors/text_transformer.py +22 -10
- pipecat/processors/transcript_processor.py +48 -29
- pipecat/processors/user_idle_processor.py +31 -21
- pipecat/runner/__init__.py +1 -0
- pipecat/runner/daily.py +132 -0
- pipecat/runner/livekit.py +148 -0
- pipecat/runner/run.py +543 -0
- pipecat/runner/types.py +67 -0
- pipecat/runner/utils.py +515 -0
- pipecat/serializers/base_serializer.py +42 -0
- pipecat/serializers/exotel.py +17 -6
- pipecat/serializers/genesys.py +95 -0
- pipecat/serializers/livekit.py +33 -0
- pipecat/serializers/plivo.py +16 -15
- pipecat/serializers/protobuf.py +37 -1
- pipecat/serializers/telnyx.py +18 -17
- pipecat/serializers/twilio.py +32 -16
- pipecat/services/ai_service.py +5 -3
- pipecat/services/anthropic/llm.py +113 -43
- pipecat/services/assemblyai/models.py +63 -5
- pipecat/services/assemblyai/stt.py +64 -11
- pipecat/services/asyncai/__init__.py +0 -0
- pipecat/services/asyncai/tts.py +501 -0
- pipecat/services/aws/llm.py +185 -111
- pipecat/services/aws/stt.py +217 -23
- pipecat/services/aws/tts.py +118 -52
- pipecat/services/aws/utils.py +101 -5
- pipecat/services/aws_nova_sonic/aws.py +82 -64
- pipecat/services/aws_nova_sonic/context.py +15 -6
- pipecat/services/azure/common.py +10 -2
- pipecat/services/azure/image.py +32 -0
- pipecat/services/azure/llm.py +9 -7
- pipecat/services/azure/stt.py +65 -2
- pipecat/services/azure/tts.py +154 -23
- pipecat/services/cartesia/stt.py +125 -8
- pipecat/services/cartesia/tts.py +102 -38
- pipecat/services/cerebras/llm.py +15 -23
- pipecat/services/deepgram/stt.py +19 -11
- pipecat/services/deepgram/tts.py +36 -0
- pipecat/services/deepseek/llm.py +14 -23
- pipecat/services/elevenlabs/tts.py +330 -64
- pipecat/services/fal/image.py +43 -0
- pipecat/services/fal/stt.py +48 -10
- pipecat/services/fireworks/llm.py +14 -21
- pipecat/services/fish/tts.py +109 -9
- pipecat/services/gemini_multimodal_live/__init__.py +1 -0
- pipecat/services/gemini_multimodal_live/events.py +83 -2
- pipecat/services/gemini_multimodal_live/file_api.py +189 -0
- pipecat/services/gemini_multimodal_live/gemini.py +218 -21
- pipecat/services/gladia/config.py +17 -10
- pipecat/services/gladia/stt.py +82 -36
- pipecat/services/google/frames.py +40 -0
- pipecat/services/google/google.py +2 -0
- pipecat/services/google/image.py +39 -2
- pipecat/services/google/llm.py +176 -58
- pipecat/services/google/llm_openai.py +26 -4
- pipecat/services/google/llm_vertex.py +37 -15
- pipecat/services/google/rtvi.py +41 -0
- pipecat/services/google/stt.py +65 -17
- pipecat/services/google/test-google-chirp.py +45 -0
- pipecat/services/google/tts.py +390 -19
- pipecat/services/grok/llm.py +8 -6
- pipecat/services/groq/llm.py +8 -6
- pipecat/services/groq/stt.py +13 -9
- pipecat/services/groq/tts.py +40 -0
- pipecat/services/hamsa/__init__.py +9 -0
- pipecat/services/hamsa/stt.py +241 -0
- pipecat/services/heygen/__init__.py +5 -0
- pipecat/services/heygen/api.py +281 -0
- pipecat/services/heygen/client.py +620 -0
- pipecat/services/heygen/video.py +338 -0
- pipecat/services/image_service.py +5 -3
- pipecat/services/inworld/__init__.py +1 -0
- pipecat/services/inworld/tts.py +592 -0
- pipecat/services/llm_service.py +127 -45
- pipecat/services/lmnt/tts.py +80 -7
- pipecat/services/mcp_service.py +85 -44
- pipecat/services/mem0/memory.py +42 -13
- pipecat/services/minimax/tts.py +74 -15
- pipecat/services/mistral/__init__.py +0 -0
- pipecat/services/mistral/llm.py +185 -0
- pipecat/services/moondream/vision.py +55 -10
- pipecat/services/neuphonic/tts.py +275 -48
- pipecat/services/nim/llm.py +8 -6
- pipecat/services/ollama/llm.py +27 -7
- pipecat/services/openai/base_llm.py +54 -16
- pipecat/services/openai/image.py +30 -0
- pipecat/services/openai/llm.py +7 -5
- pipecat/services/openai/stt.py +13 -9
- pipecat/services/openai/tts.py +42 -10
- pipecat/services/openai_realtime_beta/azure.py +11 -9
- pipecat/services/openai_realtime_beta/context.py +7 -5
- pipecat/services/openai_realtime_beta/events.py +10 -7
- pipecat/services/openai_realtime_beta/openai.py +37 -18
- pipecat/services/openpipe/llm.py +30 -24
- pipecat/services/openrouter/llm.py +9 -7
- pipecat/services/perplexity/llm.py +15 -19
- pipecat/services/piper/tts.py +26 -12
- pipecat/services/playht/tts.py +227 -65
- pipecat/services/qwen/llm.py +8 -6
- pipecat/services/rime/tts.py +128 -17
- pipecat/services/riva/stt.py +160 -22
- pipecat/services/riva/tts.py +67 -2
- pipecat/services/sambanova/llm.py +19 -17
- pipecat/services/sambanova/stt.py +14 -8
- pipecat/services/sarvam/tts.py +60 -13
- pipecat/services/simli/video.py +82 -21
- pipecat/services/soniox/__init__.py +0 -0
- pipecat/services/soniox/stt.py +398 -0
- pipecat/services/speechmatics/stt.py +29 -17
- pipecat/services/stt_service.py +47 -11
- pipecat/services/tavus/video.py +94 -25
- pipecat/services/together/llm.py +8 -6
- pipecat/services/tts_service.py +77 -53
- pipecat/services/ultravox/stt.py +46 -43
- pipecat/services/vision_service.py +5 -3
- pipecat/services/websocket_service.py +12 -11
- pipecat/services/whisper/base_stt.py +58 -12
- pipecat/services/whisper/stt.py +69 -58
- pipecat/services/xtts/tts.py +59 -2
- pipecat/sync/base_notifier.py +19 -0
- pipecat/sync/event_notifier.py +24 -0
- pipecat/tests/utils.py +73 -5
- pipecat/transcriptions/language.py +24 -0
- pipecat/transports/base_input.py +112 -8
- pipecat/transports/base_output.py +235 -13
- pipecat/transports/base_transport.py +119 -0
- pipecat/transports/local/audio.py +76 -0
- pipecat/transports/local/tk.py +84 -0
- pipecat/transports/network/fastapi_websocket.py +174 -15
- pipecat/transports/network/small_webrtc.py +383 -39
- pipecat/transports/network/webrtc_connection.py +214 -8
- pipecat/transports/network/websocket_client.py +171 -1
- pipecat/transports/network/websocket_server.py +147 -9
- pipecat/transports/services/daily.py +792 -70
- pipecat/transports/services/helpers/daily_rest.py +122 -129
- pipecat/transports/services/livekit.py +339 -4
- pipecat/transports/services/tavus.py +273 -38
- pipecat/utils/asyncio/task_manager.py +92 -186
- pipecat/utils/base_object.py +83 -1
- pipecat/utils/network.py +2 -0
- pipecat/utils/string.py +114 -58
- pipecat/utils/text/base_text_aggregator.py +44 -13
- pipecat/utils/text/base_text_filter.py +46 -0
- pipecat/utils/text/markdown_text_filter.py +70 -14
- pipecat/utils/text/pattern_pair_aggregator.py +18 -14
- pipecat/utils/text/simple_text_aggregator.py +43 -2
- pipecat/utils/text/skip_tags_aggregator.py +21 -13
- pipecat/utils/time.py +36 -0
- pipecat/utils/tracing/class_decorators.py +32 -7
- pipecat/utils/tracing/conversation_context_provider.py +12 -2
- pipecat/utils/tracing/service_attributes.py +80 -64
- pipecat/utils/tracing/service_decorators.py +48 -21
- pipecat/utils/tracing/setup.py +13 -7
- pipecat/utils/tracing/turn_context_provider.py +12 -2
- pipecat/utils/tracing/turn_trace_observer.py +27 -0
- pipecat/utils/utils.py +14 -14
- dv_pipecat_ai-0.0.74.dev770.dist-info/RECORD +0 -319
- pipecat/examples/daily_runner.py +0 -64
- pipecat/examples/run.py +0 -265
- pipecat/utils/asyncio/watchdog_async_iterator.py +0 -72
- pipecat/utils/asyncio/watchdog_event.py +0 -42
- pipecat/utils/asyncio/watchdog_priority_queue.py +0 -48
- pipecat/utils/asyncio/watchdog_queue.py +0 -48
- {dv_pipecat_ai-0.0.74.dev770.dist-info → dv_pipecat_ai-0.0.82.dev776.dist-info}/WHEEL +0 -0
- {dv_pipecat_ai-0.0.74.dev770.dist-info → dv_pipecat_ai-0.0.82.dev776.dist-info}/licenses/LICENSE +0 -0
- {dv_pipecat_ai-0.0.74.dev770.dist-info → dv_pipecat_ai-0.0.82.dev776.dist-info}/top_level.txt +0 -0
- /pipecat/{examples → extensions}/__init__.py +0 -0
|
@@ -4,6 +4,13 @@
|
|
|
4
4
|
# SPDX-License-Identifier: BSD 2-Clause License
|
|
5
5
|
#
|
|
6
6
|
|
|
7
|
+
"""Base transport classes for Pipecat.
|
|
8
|
+
|
|
9
|
+
This module provides the foundation for transport implementations including
|
|
10
|
+
parameter configuration and abstract base classes for input/output transport
|
|
11
|
+
functionality.
|
|
12
|
+
"""
|
|
13
|
+
|
|
7
14
|
from abc import abstractmethod
|
|
8
15
|
from typing import List, Mapping, Optional
|
|
9
16
|
|
|
@@ -18,6 +25,95 @@ from pipecat.utils.base_object import BaseObject
|
|
|
18
25
|
|
|
19
26
|
|
|
20
27
|
class TransportParams(BaseModel):
|
|
28
|
+
"""Configuration parameters for transport implementations.
|
|
29
|
+
|
|
30
|
+
Parameters:
|
|
31
|
+
camera_in_enabled: Enable camera input (deprecated, use video_in_enabled).
|
|
32
|
+
|
|
33
|
+
.. deprecated:: 0.0.66
|
|
34
|
+
The `camera_in_enabled` parameter is deprecated, use
|
|
35
|
+
`video_in_enabled` instead.
|
|
36
|
+
|
|
37
|
+
camera_out_enabled: Enable camera output (deprecated, use video_out_enabled).
|
|
38
|
+
|
|
39
|
+
.. deprecated:: 0.0.66
|
|
40
|
+
The `camera_out_enabled` parameter is deprecated, use
|
|
41
|
+
`video_out_enabled` instead.
|
|
42
|
+
|
|
43
|
+
camera_out_is_live: Enable real-time camera output (deprecated).
|
|
44
|
+
|
|
45
|
+
.. deprecated:: 0.0.66
|
|
46
|
+
The `camera_out_is_live` parameter is deprecated, use
|
|
47
|
+
`video_out_is_live` instead.
|
|
48
|
+
|
|
49
|
+
camera_out_width: Camera output width in pixels (deprecated).
|
|
50
|
+
|
|
51
|
+
.. deprecated:: 0.0.66
|
|
52
|
+
The `camera_out_width` parameter is deprecated, use
|
|
53
|
+
`video_out_width` instead.
|
|
54
|
+
|
|
55
|
+
camera_out_height: Camera output height in pixels (deprecated).
|
|
56
|
+
|
|
57
|
+
.. deprecated:: 0.0.66
|
|
58
|
+
The `camera_out_height` parameter is deprecated, use
|
|
59
|
+
`video_out_height` instead.
|
|
60
|
+
|
|
61
|
+
camera_out_bitrate: Camera output bitrate in bits per second (deprecated).
|
|
62
|
+
|
|
63
|
+
.. deprecated:: 0.0.66
|
|
64
|
+
The `camera_out_bitrate` parameter is deprecated, use
|
|
65
|
+
`video_out_bitrate` instead.
|
|
66
|
+
|
|
67
|
+
camera_out_framerate: Camera output frame rate in FPS (deprecated).
|
|
68
|
+
|
|
69
|
+
.. deprecated:: 0.0.66
|
|
70
|
+
The `camera_out_framerate` parameter is deprecated, use
|
|
71
|
+
`video_out_framerate` instead.
|
|
72
|
+
|
|
73
|
+
camera_out_color_format: Camera output color format string (deprecated).
|
|
74
|
+
|
|
75
|
+
.. deprecated:: 0.0.66
|
|
76
|
+
The `camera_out_color_format` parameter is deprecated, use
|
|
77
|
+
`video_out_color_format` instead.
|
|
78
|
+
|
|
79
|
+
audio_out_enabled: Enable audio output streaming.
|
|
80
|
+
audio_out_sample_rate: Output audio sample rate in Hz.
|
|
81
|
+
audio_out_channels: Number of output audio channels.
|
|
82
|
+
audio_out_bitrate: Output audio bitrate in bits per second.
|
|
83
|
+
audio_out_10ms_chunks: Number of 10ms chunks to buffer for output.
|
|
84
|
+
audio_out_mixer: Audio mixer instance or destination mapping.
|
|
85
|
+
audio_out_destinations: List of audio output destination identifiers.
|
|
86
|
+
audio_in_enabled: Enable audio input streaming.
|
|
87
|
+
audio_in_sample_rate: Input audio sample rate in Hz.
|
|
88
|
+
audio_in_channels: Number of input audio channels.
|
|
89
|
+
audio_in_filter: Audio filter to apply to input audio.
|
|
90
|
+
audio_in_stream_on_start: Start audio streaming immediately on transport start.
|
|
91
|
+
audio_in_passthrough: Pass through input audio frames downstream.
|
|
92
|
+
video_in_enabled: Enable video input streaming.
|
|
93
|
+
video_out_enabled: Enable video output streaming.
|
|
94
|
+
video_out_is_live: Enable real-time video output streaming.
|
|
95
|
+
video_out_width: Video output width in pixels.
|
|
96
|
+
video_out_height: Video output height in pixels.
|
|
97
|
+
video_out_bitrate: Video output bitrate in bits per second.
|
|
98
|
+
video_out_framerate: Video output frame rate in FPS.
|
|
99
|
+
video_out_color_format: Video output color format string.
|
|
100
|
+
video_out_destinations: List of video output destination identifiers.
|
|
101
|
+
vad_enabled: Enable Voice Activity Detection (deprecated).
|
|
102
|
+
|
|
103
|
+
.. deprecated:: 0.0.66
|
|
104
|
+
The `vad_enabled` parameter is deprecated, use `audio_in_enabled`
|
|
105
|
+
and `TransportParams.vad_analyzer` instead.
|
|
106
|
+
|
|
107
|
+
vad_audio_passthrough: Enable VAD audio passthrough (deprecated).
|
|
108
|
+
|
|
109
|
+
.. deprecated:: 0.0.66
|
|
110
|
+
The `vad_audio_passthrough` parameter is deprecated, use `audio_in_passthrough`
|
|
111
|
+
instead.
|
|
112
|
+
|
|
113
|
+
vad_analyzer: Voice Activity Detection analyzer instance.
|
|
114
|
+
turn_analyzer: Turn-taking analyzer instance for conversation management.
|
|
115
|
+
"""
|
|
116
|
+
|
|
21
117
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
22
118
|
|
|
23
119
|
camera_in_enabled: bool = False
|
|
@@ -57,6 +153,12 @@ class TransportParams(BaseModel):
|
|
|
57
153
|
|
|
58
154
|
|
|
59
155
|
class BaseTransport(BaseObject):
|
|
156
|
+
"""Base class for transport implementations.
|
|
157
|
+
|
|
158
|
+
Provides the foundation for transport classes that handle media streaming,
|
|
159
|
+
including input and output frame processors for audio and video data.
|
|
160
|
+
"""
|
|
161
|
+
|
|
60
162
|
def __init__(
|
|
61
163
|
self,
|
|
62
164
|
*,
|
|
@@ -64,14 +166,31 @@ class BaseTransport(BaseObject):
|
|
|
64
166
|
input_name: Optional[str] = None,
|
|
65
167
|
output_name: Optional[str] = None,
|
|
66
168
|
):
|
|
169
|
+
"""Initialize the base transport.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
name: Optional name for the transport instance.
|
|
173
|
+
input_name: Optional name for the input processor.
|
|
174
|
+
output_name: Optional name for the output processor.
|
|
175
|
+
"""
|
|
67
176
|
super().__init__(name=name)
|
|
68
177
|
self._input_name = input_name
|
|
69
178
|
self._output_name = output_name
|
|
70
179
|
|
|
71
180
|
@abstractmethod
|
|
72
181
|
def input(self) -> FrameProcessor:
|
|
182
|
+
"""Get the input frame processor for this transport.
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
The frame processor that handles incoming frames.
|
|
186
|
+
"""
|
|
73
187
|
pass
|
|
74
188
|
|
|
75
189
|
@abstractmethod
|
|
76
190
|
def output(self) -> FrameProcessor:
|
|
191
|
+
"""Get the output frame processor for this transport.
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
The frame processor that handles outgoing frames.
|
|
195
|
+
"""
|
|
77
196
|
pass
|
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
# SPDX-License-Identifier: BSD 2-Clause License
|
|
5
5
|
#
|
|
6
6
|
|
|
7
|
+
"""Local audio transport implementation for Pipecat.
|
|
8
|
+
|
|
9
|
+
This module provides a local audio transport that uses PyAudio for real-time
|
|
10
|
+
audio input and output through the system's default audio devices.
|
|
11
|
+
"""
|
|
12
|
+
|
|
7
13
|
import asyncio
|
|
8
14
|
from concurrent.futures import ThreadPoolExecutor
|
|
9
15
|
from typing import Optional
|
|
@@ -27,14 +33,33 @@ except ModuleNotFoundError as e:
|
|
|
27
33
|
|
|
28
34
|
|
|
29
35
|
class LocalAudioTransportParams(TransportParams):
|
|
36
|
+
"""Configuration parameters for local audio transport.
|
|
37
|
+
|
|
38
|
+
Parameters:
|
|
39
|
+
input_device_index: PyAudio device index for audio input. If None, uses default.
|
|
40
|
+
output_device_index: PyAudio device index for audio output. If None, uses default.
|
|
41
|
+
"""
|
|
42
|
+
|
|
30
43
|
input_device_index: Optional[int] = None
|
|
31
44
|
output_device_index: Optional[int] = None
|
|
32
45
|
|
|
33
46
|
|
|
34
47
|
class LocalAudioInputTransport(BaseInputTransport):
|
|
48
|
+
"""Local audio input transport using PyAudio.
|
|
49
|
+
|
|
50
|
+
Captures audio from the system's audio input device and converts it to
|
|
51
|
+
InputAudioRawFrame objects for processing in the pipeline.
|
|
52
|
+
"""
|
|
53
|
+
|
|
35
54
|
_params: LocalAudioTransportParams
|
|
36
55
|
|
|
37
56
|
def __init__(self, py_audio: pyaudio.PyAudio, params: LocalAudioTransportParams):
|
|
57
|
+
"""Initialize the local audio input transport.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
py_audio: PyAudio instance for audio device management.
|
|
61
|
+
params: Transport configuration parameters.
|
|
62
|
+
"""
|
|
38
63
|
super().__init__(params)
|
|
39
64
|
self._py_audio = py_audio
|
|
40
65
|
|
|
@@ -42,6 +67,11 @@ class LocalAudioInputTransport(BaseInputTransport):
|
|
|
42
67
|
self._sample_rate = 0
|
|
43
68
|
|
|
44
69
|
async def start(self, frame: StartFrame):
|
|
70
|
+
"""Start the audio input stream.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
frame: The start frame containing initialization parameters.
|
|
74
|
+
"""
|
|
45
75
|
await super().start(frame)
|
|
46
76
|
|
|
47
77
|
if self._in_stream:
|
|
@@ -64,6 +94,7 @@ class LocalAudioInputTransport(BaseInputTransport):
|
|
|
64
94
|
await self.set_transport_ready(frame)
|
|
65
95
|
|
|
66
96
|
async def cleanup(self):
|
|
97
|
+
"""Stop and cleanup the audio input stream."""
|
|
67
98
|
await super().cleanup()
|
|
68
99
|
if self._in_stream:
|
|
69
100
|
self._in_stream.stop_stream()
|
|
@@ -71,6 +102,7 @@ class LocalAudioInputTransport(BaseInputTransport):
|
|
|
71
102
|
self._in_stream = None
|
|
72
103
|
|
|
73
104
|
def _audio_in_callback(self, in_data, frame_count, time_info, status):
|
|
105
|
+
"""Callback function for PyAudio input stream."""
|
|
74
106
|
frame = InputAudioRawFrame(
|
|
75
107
|
audio=in_data,
|
|
76
108
|
sample_rate=self._sample_rate,
|
|
@@ -83,9 +115,21 @@ class LocalAudioInputTransport(BaseInputTransport):
|
|
|
83
115
|
|
|
84
116
|
|
|
85
117
|
class LocalAudioOutputTransport(BaseOutputTransport):
|
|
118
|
+
"""Local audio output transport using PyAudio.
|
|
119
|
+
|
|
120
|
+
Plays audio frames through the system's audio output device by converting
|
|
121
|
+
OutputAudioRawFrame objects to playable audio data.
|
|
122
|
+
"""
|
|
123
|
+
|
|
86
124
|
_params: LocalAudioTransportParams
|
|
87
125
|
|
|
88
126
|
def __init__(self, py_audio: pyaudio.PyAudio, params: LocalAudioTransportParams):
|
|
127
|
+
"""Initialize the local audio output transport.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
py_audio: PyAudio instance for audio device management.
|
|
131
|
+
params: Transport configuration parameters.
|
|
132
|
+
"""
|
|
89
133
|
super().__init__(params)
|
|
90
134
|
self._py_audio = py_audio
|
|
91
135
|
|
|
@@ -97,6 +141,11 @@ class LocalAudioOutputTransport(BaseOutputTransport):
|
|
|
97
141
|
self._executor = ThreadPoolExecutor(max_workers=1)
|
|
98
142
|
|
|
99
143
|
async def start(self, frame: StartFrame):
|
|
144
|
+
"""Start the audio output stream.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
frame: The start frame containing initialization parameters.
|
|
148
|
+
"""
|
|
100
149
|
await super().start(frame)
|
|
101
150
|
|
|
102
151
|
if self._out_stream:
|
|
@@ -116,6 +165,7 @@ class LocalAudioOutputTransport(BaseOutputTransport):
|
|
|
116
165
|
await self.set_transport_ready(frame)
|
|
117
166
|
|
|
118
167
|
async def cleanup(self):
|
|
168
|
+
"""Stop and cleanup the audio output stream."""
|
|
119
169
|
await super().cleanup()
|
|
120
170
|
if self._out_stream:
|
|
121
171
|
self._out_stream.stop_stream()
|
|
@@ -123,6 +173,11 @@ class LocalAudioOutputTransport(BaseOutputTransport):
|
|
|
123
173
|
self._out_stream = None
|
|
124
174
|
|
|
125
175
|
async def write_audio_frame(self, frame: OutputAudioRawFrame):
|
|
176
|
+
"""Write an audio frame to the output stream.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
frame: The audio frame to write to the output device.
|
|
180
|
+
"""
|
|
126
181
|
if self._out_stream:
|
|
127
182
|
await self.get_event_loop().run_in_executor(
|
|
128
183
|
self._executor, self._out_stream.write, frame.audio
|
|
@@ -130,7 +185,18 @@ class LocalAudioOutputTransport(BaseOutputTransport):
|
|
|
130
185
|
|
|
131
186
|
|
|
132
187
|
class LocalAudioTransport(BaseTransport):
|
|
188
|
+
"""Complete local audio transport with input and output capabilities.
|
|
189
|
+
|
|
190
|
+
Provides a unified interface for local audio I/O using PyAudio, supporting
|
|
191
|
+
both audio capture and playback through the system's audio devices.
|
|
192
|
+
"""
|
|
193
|
+
|
|
133
194
|
def __init__(self, params: LocalAudioTransportParams):
|
|
195
|
+
"""Initialize the local audio transport.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
params: Transport configuration parameters.
|
|
199
|
+
"""
|
|
134
200
|
super().__init__()
|
|
135
201
|
self._params = params
|
|
136
202
|
self._pyaudio = pyaudio.PyAudio()
|
|
@@ -143,11 +209,21 @@ class LocalAudioTransport(BaseTransport):
|
|
|
143
209
|
#
|
|
144
210
|
|
|
145
211
|
def input(self) -> FrameProcessor:
|
|
212
|
+
"""Get the input frame processor for this transport.
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
The audio input transport processor.
|
|
216
|
+
"""
|
|
146
217
|
if not self._input:
|
|
147
218
|
self._input = LocalAudioInputTransport(self._pyaudio, self._params)
|
|
148
219
|
return self._input
|
|
149
220
|
|
|
150
221
|
def output(self) -> FrameProcessor:
|
|
222
|
+
"""Get the output frame processor for this transport.
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
The audio output transport processor.
|
|
226
|
+
"""
|
|
151
227
|
if not self._output:
|
|
152
228
|
self._output = LocalAudioOutputTransport(self._pyaudio, self._params)
|
|
153
229
|
return self._output
|
pipecat/transports/local/tk.py
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
# SPDX-License-Identifier: BSD 2-Clause License
|
|
5
5
|
#
|
|
6
6
|
|
|
7
|
+
"""Tkinter-based local transport implementation for Pipecat.
|
|
8
|
+
|
|
9
|
+
This module provides a local transport using Tkinter for video display and
|
|
10
|
+
PyAudio for audio I/O, suitable for desktop applications and testing.
|
|
11
|
+
"""
|
|
12
|
+
|
|
7
13
|
import asyncio
|
|
8
14
|
import tkinter as tk
|
|
9
15
|
from concurrent.futures import ThreadPoolExecutor
|
|
@@ -40,20 +46,44 @@ except ModuleNotFoundError as e:
|
|
|
40
46
|
|
|
41
47
|
|
|
42
48
|
class TkTransportParams(TransportParams):
|
|
49
|
+
"""Configuration parameters for Tkinter transport.
|
|
50
|
+
|
|
51
|
+
Parameters:
|
|
52
|
+
audio_input_device_index: PyAudio device index for audio input. If None, uses default.
|
|
53
|
+
audio_output_device_index: PyAudio device index for audio output. If None, uses default.
|
|
54
|
+
"""
|
|
55
|
+
|
|
43
56
|
audio_input_device_index: Optional[int] = None
|
|
44
57
|
audio_output_device_index: Optional[int] = None
|
|
45
58
|
|
|
46
59
|
|
|
47
60
|
class TkInputTransport(BaseInputTransport):
|
|
61
|
+
"""Tkinter-based audio input transport.
|
|
62
|
+
|
|
63
|
+
Captures audio from the system's audio input device using PyAudio and
|
|
64
|
+
converts it to InputAudioRawFrame objects for pipeline processing.
|
|
65
|
+
"""
|
|
66
|
+
|
|
48
67
|
_params: TkTransportParams
|
|
49
68
|
|
|
50
69
|
def __init__(self, py_audio: pyaudio.PyAudio, params: TkTransportParams):
|
|
70
|
+
"""Initialize the Tkinter input transport.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
py_audio: PyAudio instance for audio device management.
|
|
74
|
+
params: Transport configuration parameters.
|
|
75
|
+
"""
|
|
51
76
|
super().__init__(params)
|
|
52
77
|
self._py_audio = py_audio
|
|
53
78
|
self._in_stream = None
|
|
54
79
|
self._sample_rate = 0
|
|
55
80
|
|
|
56
81
|
async def start(self, frame: StartFrame):
|
|
82
|
+
"""Start the audio input stream.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
frame: The start frame containing initialization parameters.
|
|
86
|
+
"""
|
|
57
87
|
await super().start(frame)
|
|
58
88
|
|
|
59
89
|
if self._in_stream:
|
|
@@ -76,6 +106,7 @@ class TkInputTransport(BaseInputTransport):
|
|
|
76
106
|
await self.set_transport_ready(frame)
|
|
77
107
|
|
|
78
108
|
async def cleanup(self):
|
|
109
|
+
"""Stop and cleanup the audio input stream."""
|
|
79
110
|
await super().cleanup()
|
|
80
111
|
if self._in_stream:
|
|
81
112
|
self._in_stream.stop_stream()
|
|
@@ -83,6 +114,7 @@ class TkInputTransport(BaseInputTransport):
|
|
|
83
114
|
self._in_stream = None
|
|
84
115
|
|
|
85
116
|
def _audio_in_callback(self, in_data, frame_count, time_info, status):
|
|
117
|
+
"""Callback function for PyAudio input stream."""
|
|
86
118
|
frame = InputAudioRawFrame(
|
|
87
119
|
audio=in_data,
|
|
88
120
|
sample_rate=self._sample_rate,
|
|
@@ -95,9 +127,22 @@ class TkInputTransport(BaseInputTransport):
|
|
|
95
127
|
|
|
96
128
|
|
|
97
129
|
class TkOutputTransport(BaseOutputTransport):
|
|
130
|
+
"""Tkinter-based audio and video output transport.
|
|
131
|
+
|
|
132
|
+
Plays audio through PyAudio and displays video frames in a Tkinter window,
|
|
133
|
+
providing a complete multimedia output solution for desktop applications.
|
|
134
|
+
"""
|
|
135
|
+
|
|
98
136
|
_params: TkTransportParams
|
|
99
137
|
|
|
100
138
|
def __init__(self, tk_root: tk.Tk, py_audio: pyaudio.PyAudio, params: TkTransportParams):
|
|
139
|
+
"""Initialize the Tkinter output transport.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
tk_root: The root Tkinter window for video display.
|
|
143
|
+
py_audio: PyAudio instance for audio device management.
|
|
144
|
+
params: Transport configuration parameters.
|
|
145
|
+
"""
|
|
101
146
|
super().__init__(params)
|
|
102
147
|
self._py_audio = py_audio
|
|
103
148
|
self._out_stream = None
|
|
@@ -115,6 +160,11 @@ class TkOutputTransport(BaseOutputTransport):
|
|
|
115
160
|
self._image_label.pack()
|
|
116
161
|
|
|
117
162
|
async def start(self, frame: StartFrame):
|
|
163
|
+
"""Start the audio output stream.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
frame: The start frame containing initialization parameters.
|
|
167
|
+
"""
|
|
118
168
|
await super().start(frame)
|
|
119
169
|
|
|
120
170
|
if self._out_stream:
|
|
@@ -134,6 +184,7 @@ class TkOutputTransport(BaseOutputTransport):
|
|
|
134
184
|
await self.set_transport_ready(frame)
|
|
135
185
|
|
|
136
186
|
async def cleanup(self):
|
|
187
|
+
"""Stop and cleanup the audio output stream."""
|
|
137
188
|
await super().cleanup()
|
|
138
189
|
if self._out_stream:
|
|
139
190
|
self._out_stream.stop_stream()
|
|
@@ -141,15 +192,26 @@ class TkOutputTransport(BaseOutputTransport):
|
|
|
141
192
|
self._out_stream = None
|
|
142
193
|
|
|
143
194
|
async def write_audio_frame(self, frame: OutputAudioRawFrame):
|
|
195
|
+
"""Write an audio frame to the output stream.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
frame: The audio frame to write to the output device.
|
|
199
|
+
"""
|
|
144
200
|
if self._out_stream:
|
|
145
201
|
await self.get_event_loop().run_in_executor(
|
|
146
202
|
self._executor, self._out_stream.write, frame.audio
|
|
147
203
|
)
|
|
148
204
|
|
|
149
205
|
async def write_video_frame(self, frame: OutputImageRawFrame):
|
|
206
|
+
"""Write a video frame to the Tkinter display.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
frame: The video frame to display in the Tkinter window.
|
|
210
|
+
"""
|
|
150
211
|
self.get_event_loop().call_soon(self._write_frame_to_tk, frame)
|
|
151
212
|
|
|
152
213
|
def _write_frame_to_tk(self, frame: OutputImageRawFrame):
|
|
214
|
+
"""Write frame data to the Tkinter image label."""
|
|
153
215
|
width = frame.size[0]
|
|
154
216
|
height = frame.size[1]
|
|
155
217
|
data = f"P6 {width} {height} 255 ".encode() + frame.image
|
|
@@ -162,7 +224,19 @@ class TkOutputTransport(BaseOutputTransport):
|
|
|
162
224
|
|
|
163
225
|
|
|
164
226
|
class TkLocalTransport(BaseTransport):
|
|
227
|
+
"""Complete Tkinter-based local transport with audio and video capabilities.
|
|
228
|
+
|
|
229
|
+
Provides a unified interface for local multimedia I/O using Tkinter for video
|
|
230
|
+
display and PyAudio for audio, suitable for desktop applications and testing.
|
|
231
|
+
"""
|
|
232
|
+
|
|
165
233
|
def __init__(self, tk_root: tk.Tk, params: TkTransportParams):
|
|
234
|
+
"""Initialize the Tkinter local transport.
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
tk_root: The root Tkinter window for video display.
|
|
238
|
+
params: Transport configuration parameters.
|
|
239
|
+
"""
|
|
166
240
|
super().__init__()
|
|
167
241
|
self._tk_root = tk_root
|
|
168
242
|
self._params = params
|
|
@@ -176,11 +250,21 @@ class TkLocalTransport(BaseTransport):
|
|
|
176
250
|
#
|
|
177
251
|
|
|
178
252
|
def input(self) -> TkInputTransport:
|
|
253
|
+
"""Get the input frame processor for this transport.
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
The Tkinter input transport processor.
|
|
257
|
+
"""
|
|
179
258
|
if not self._input:
|
|
180
259
|
self._input = TkInputTransport(self._pyaudio, self._params)
|
|
181
260
|
return self._input
|
|
182
261
|
|
|
183
262
|
def output(self) -> TkOutputTransport:
|
|
263
|
+
"""Get the output frame processor for this transport.
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
The Tkinter output transport processor.
|
|
267
|
+
"""
|
|
184
268
|
if not self._output:
|
|
185
269
|
self._output = TkOutputTransport(self._tk_root, self._pyaudio, self._params)
|
|
186
270
|
return self._output
|