Merge pull request #613 from pipecat-ai/aleix/examples-endframe

examples: use EndFrame() when the participant leaves
This commit is contained in:
Aleix Conchillo Flaqué
2024-10-18 11:18:26 -07:00
committed by GitHub
5 changed files with 52 additions and 42 deletions

View File

@@ -51,10 +51,7 @@ Your project may or may not need these, so they're made available as optional re
Here is a very basic Pipecat bot that greets a user when they join a real-time session. We'll use [Daily](https://daily.co) for real-time media transport, and [Cartesia](https://cartesia.ai/) for text-to-speech. Here is a very basic Pipecat bot that greets a user when they join a real-time session. We'll use [Daily](https://daily.co) for real-time media transport, and [Cartesia](https://cartesia.ai/) for text-to-speech.
```python ```python
#app.py
import asyncio import asyncio
import aiohttp
from pipecat.frames.frames import EndFrame, TextFrame from pipecat.frames.frames import EndFrame, TextFrame
from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.pipeline import Pipeline
@@ -64,39 +61,43 @@ from pipecat.services.cartesia import CartesiaTTSService
from pipecat.transports.services.daily import DailyParams, DailyTransport from pipecat.transports.services.daily import DailyParams, DailyTransport
async def main(): async def main():
async with aiohttp.ClientSession() as session: # Use Daily as a real-time media transport (WebRTC)
# Use Daily as a real-time media transport (WebRTC) transport = DailyTransport(
transport = DailyTransport( room_url=...,
room_url=..., token=...,
token=..., bot_name="Bot Name",
bot_name="Bot Name", params=DailyParams(audio_out_enabled=True))
params=DailyParams(audio_out_enabled=True))
# Use Cartesia for Text-to-Speech # Use Cartesia for Text-to-Speech
tts = CartesiaTTSService( tts = CartesiaTTSService(
api_key=..., api_key=...,
voice_id=... voice_id=...
) )
# Simple pipeline that will process text to speech and output the result # Simple pipeline that will process text to speech and output the result
pipeline = Pipeline([tts, transport.output()]) pipeline = Pipeline([tts, transport.output()])
# Create Pipecat processor that can run one or more pipelines tasks # Create Pipecat processor that can run one or more pipelines tasks
runner = PipelineRunner() runner = PipelineRunner()
# Assign the task callable to run the pipeline # Assign the task callable to run the pipeline
task = PipelineTask(pipeline) task = PipelineTask(pipeline)
# Register an event handler to play audio when a # Register an event handler to play audio when a
# participant joins the transport WebRTC session # participant joins the transport WebRTC session
@transport.event_handler("on_participant_joined") @transport.event_handler("on_first_participant_joined")
async def on_new_participant_joined(transport, participant): async def on_first_participant_joined(transport, participant):
participant_name = participant["info"]["userName"] or '' participant_name = participant.get("info", {}).get("userName", "")
# Queue a TextFrame that will get spoken by the TTS service (Cartesia) # Queue a TextFrame that will get spoken by the TTS service (Cartesia)
await task.queue_frames([TextFrame(f"Hello there, {participant_name}!"), EndFrame()]) await task.queue_frame(TextFrame(f"Hello there, {participant_name}!"))
# Run the pipeline task # Register an event handler to exit the application when the user leaves.
await runner.run(task) @transport.event_handler("on_participant_left")
async def on_participant_left(transport, participant, reason):
await task.queue_frame(EndFrame())
# Run the pipeline task
await runner.run(task)
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(main()) asyncio.run(main())

View File

@@ -47,10 +47,15 @@ async def main():
# Register an event handler so we can play the audio when the # Register an event handler so we can play the audio when the
# participant joins. # participant joins.
@transport.event_handler("on_participant_joined") @transport.event_handler("on_first_participant_joined")
async def on_new_participant_joined(transport, participant): async def on_first_participant_joined(transport, participant):
participant_name = participant["info"]["userName"] or "" participant_name = participant.get("info", {}).get("userName", "")
await task.queue_frames([TextFrame(f"Hello there, {participant_name}!"), EndFrame()]) await task.queue_frame(TextFrame(f"Hello there, {participant_name}!"))
# Register an event handler to exit the application when the user leaves.
@transport.event_handler("on_participant_left")
async def on_participant_left(transport, participant, reason):
await task.queue_frame(EndFrame())
await runner.run(task) await runner.run(task)

View File

@@ -57,7 +57,11 @@ async def main():
@transport.event_handler("on_first_participant_joined") @transport.event_handler("on_first_participant_joined")
async def on_first_participant_joined(transport, participant): async def on_first_participant_joined(transport, participant):
await task.queue_frames([LLMMessagesFrame(messages), EndFrame()]) await task.queue_frame(LLMMessagesFrame(messages))
@transport.event_handler("on_participant_left")
async def on_participant_left(transport, participant, reason):
await task.queue_frame(EndFrame())
await runner.run(task) await runner.run(task)

View File

@@ -9,7 +9,7 @@ import aiohttp
import os import os
import sys import sys
from pipecat.frames.frames import TextFrame from pipecat.frames.frames import EndFrame, TextFrame
from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.pipeline import Pipeline
from pipecat.pipeline.runner import PipelineRunner from pipecat.pipeline.runner import PipelineRunner
from pipecat.pipeline.task import PipelineTask from pipecat.pipeline.task import PipelineTask
@@ -51,11 +51,11 @@ async def main():
@transport.event_handler("on_first_participant_joined") @transport.event_handler("on_first_participant_joined")
async def on_first_participant_joined(transport, participant): async def on_first_participant_joined(transport, participant):
# Note that we do not put an EndFrame() item in the pipeline for this demo. await task.queue_frame(TextFrame("a cat in the style of picasso"))
# This means that the bot will stay in the channel until it times out.
# An EndFrame() in the pipeline would cause the transport to shut @transport.event_handler("on_participant_left")
# down. async def on_participant_left(transport, participant, reason):
await task.queue_frames([TextFrame("a cat in the style of picasso")]) await task.queue_frame(EndFrame())
await runner.run(task) await runner.run(task)

View File

@@ -129,7 +129,7 @@ async def main():
@transport.event_handler("on_first_participant_joined") @transport.event_handler("on_first_participant_joined")
async def on_first_participant_joined(transport, participant): async def on_first_participant_joined(transport, participant):
participant_name = participant["info"]["userName"] or "" participant_name = participant.get("info", {}).get("userName", "")
transport.capture_participant_transcription(participant["id"]) transport.capture_participant_transcription(participant["id"])
await task.queue_frames([TextFrame(f"Hi there {participant_name}!")]) await task.queue_frames([TextFrame(f"Hi there {participant_name}!")])