diff --git a/examples/foundational/15-websocket-server.py b/examples/foundational/15-websocket-server.py
new file mode 100644
index 000000000..bb2579a68
--- /dev/null
+++ b/examples/foundational/15-websocket-server.py
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2024, Daily
+#
+# SPDX-License-Identifier: BSD 2-Clause License
+#
+
+import asyncio
+import sys
+
+from pipecat.pipeline.pipeline import Pipeline
+from pipecat.pipeline.runner import PipelineRunner
+from pipecat.pipeline.task import PipelineTask
+from pipecat.transports.network.websocket_server import WebsocketServerTransport
+
+from runner import configure
+
+from loguru import logger
+
+from dotenv import load_dotenv
+load_dotenv(override=True)
+
+logger.remove(0)
+logger.add(sys.stderr, level="DEBUG")
+
+
+async def main():
+ transport = WebsocketServerTransport()
+
+ pipeline = Pipeline([transport.input(), transport.output()])
+
+ task = PipelineTask(pipeline)
+
+ runner = PipelineRunner()
+
+ await runner.run(task)
+
+
+if __name__ == "__main__":
+ asyncio.run(main())
diff --git a/examples/foundational/websocket-server/frames.proto b/examples/foundational/websocket-server/frames.proto
index 830e3062c..69ac1d460 100644
--- a/examples/foundational/websocket-server/frames.proto
+++ b/examples/foundational/websocket-server/frames.proto
@@ -1,25 +1,35 @@
+//
+// Copyright (c) 2024, Daily
+//
+// SPDX-License-Identifier: BSD 2-Clause License
+//
+
+// Generate frames_pb2.py with:
+//
+// python -m grpc_tools.protoc --proto_path=./ --python_out=./protobufs frames.proto
+
syntax = "proto3";
-package pipecat_proto;
+package pipecat;
message TextFrame {
string text = 1;
}
-message AudioFrame {
+message AudioRawFrame {
bytes audio = 1;
}
message TranscriptionFrame {
string text = 1;
- string participant_id = 2;
+ string user_id = 2;
string timestamp = 3;
}
message Frame {
oneof frame {
TextFrame text = 1;
- AudioFrame audio = 2;
+ AudioRawFrame audio = 2;
TranscriptionFrame transcription = 3;
}
}
diff --git a/examples/foundational/websocket-server/index.html b/examples/foundational/websocket-server/index.html
index a38e1e78b..247ab9432 100644
--- a/examples/foundational/websocket-server/index.html
+++ b/examples/foundational/websocket-server/index.html
@@ -4,7 +4,7 @@
-
+
WebSocket Audio Stream
@@ -28,7 +28,7 @@
const proto = protobuf.load("frames.proto", (err, root) => {
if (err) throw err;
- frame = root.lookupType("pipecat_proto.Frame");
+ frame = root.lookupType("pipecat.Frame");
});
function initWebSocket() {
diff --git a/examples/foundational/websocket-server/sample.py b/examples/foundational/websocket-server/sample.py
deleted file mode 100644
index b3a4a731d..000000000
--- a/examples/foundational/websocket-server/sample.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import asyncio
-import aiohttp
-import logging
-import os
-from pipecat.pipeline.frame_processor import FrameProcessor
-from pipecat.pipeline.frames import TextFrame, TranscriptionFrame
-from pipecat.pipeline.pipeline import Pipeline
-from pipecat.services.elevenlabs_ai_services import ElevenLabsTTSService
-from pipecat.transports.websocket_transport import WebsocketTransport
-from pipecat.services.whisper_ai_services import WhisperSTTService
-
-logging.basicConfig(format="%(levelno)s %(asctime)s %(message)s")
-logger = logging.getLogger("pipecat")
-logger.setLevel(logging.DEBUG)
-
-
-class WhisperTranscriber(FrameProcessor):
- async def process_frame(self, frame):
- if isinstance(frame, TranscriptionFrame):
- print(f"Transcribed: {frame.text}")
- else:
- yield frame
-
-
-async def main():
- async with aiohttp.ClientSession() as session:
- transport = WebsocketTransport(
- mic_enabled=True,
- speaker_enabled=True,
- )
- tts = ElevenLabsTTSService(
- aiohttp_session=session,
- api_key=os.getenv("ELEVENLABS_API_KEY"),
- voice_id=os.getenv("ELEVENLABS_VOICE_ID"),
- )
-
- pipeline = Pipeline([
- WhisperSTTService(),
- WhisperTranscriber(),
- tts,
- ])
-
- @transport.on_connection
- async def queue_frame():
- await pipeline.queue_frames([TextFrame("Hello there!")])
-
- await transport.run(pipeline)
-
-if __name__ == "__main__":
- asyncio.run(main())
diff --git a/examples/foundational/websocket-server/server.py b/examples/foundational/websocket-server/server.py
new file mode 100644
index 000000000..bf75b7461
--- /dev/null
+++ b/examples/foundational/websocket-server/server.py
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2024, Daily
+#
+# SPDX-License-Identifier: BSD 2-Clause License
+#
+
+import aiohttp
+import asyncio
+import os
+import sys
+
+from loguru import logger
+from pipecat.frames.frames import Frame, TextFrame, TranscriptionFrame
+from pipecat.pipeline.pipeline import Pipeline
+from pipecat.pipeline.runner import PipelineRunner
+from pipecat.pipeline.task import PipelineTask
+
+from pipecat.processors.frame_processor import FrameDirection, FrameProcessor
+from pipecat.services.elevenlabs import ElevenLabsTTSService
+from pipecat.services.whisper import WhisperSTTService
+from pipecat.transports.network.websocket_server import WebsocketServerTransport
+
+logger.remove(0)
+logger.add(sys.stderr, level="DEBUG")
+
+
+class WhisperTranscriber(FrameProcessor):
+ async def process_frame(self, frame: Frame, direction: FrameDirection):
+ if isinstance(frame, TranscriptionFrame):
+ print(f"Transcribed: {frame.text}")
+ else:
+ await self.push_frame(frame, direction)
+
+
+async def main():
+ async with aiohttp.ClientSession() as session:
+ transport = WebsocketServerTransport()
+
+ tts = ElevenLabsTTSService(
+ aiohttp_session=session,
+ api_key=os.getenv("ELEVENLABS_API_KEY"),
+ voice_id=os.getenv("ELEVENLABS_VOICE_ID"),
+ )
+
+ pipeline = Pipeline([
+ transport.input(),
+ WhisperSTTService(),
+ WhisperTranscriber(),
+ tts,
+ transport.output(),
+ ])
+
+ task = PipelineTask(pipeline)
+
+ @transport.event_handler("on_client_connected")
+ async def on_client_connected(transport, client):
+ print("AAAAAAAA")
+ await task.queue_frame(TextFrame("Hello there!"))
+
+ runner = PipelineRunner()
+
+ await runner.run(task)
+
+if __name__ == "__main__":
+ asyncio.run(main())