|
| 1 | +import asyncio |
| 2 | +import logging |
| 3 | + |
| 4 | +from dotenv import load_dotenv |
| 5 | +from livekit import rtc |
| 6 | +from livekit.agents import AutoSubscribe, JobContext, WorkerOptions, cli |
| 7 | +from livekit.plugins import neuphonic |
| 8 | + |
| 9 | +load_dotenv() |
| 10 | + |
| 11 | +logger = logging.getLogger("neuphonic-tts-demo") |
| 12 | +logger.setLevel(logging.INFO) |
| 13 | + |
| 14 | + |
| 15 | +async def entrypoint(job: JobContext): |
| 16 | + logger.info("starting tts example agent") |
| 17 | + |
| 18 | + SAMPLE_RATE = 22050 |
| 19 | + NUM_CHANNELS = 1 |
| 20 | + |
| 21 | + tts = neuphonic.TTS( |
| 22 | + # voice_id=<uuid>, |
| 23 | + sample_rate=SAMPLE_RATE # defaults to 22050 |
| 24 | + ) |
| 25 | + |
| 26 | + source = rtc.AudioSource(SAMPLE_RATE, NUM_CHANNELS) |
| 27 | + track = rtc.LocalAudioTrack.create_audio_track("agent-mic", source) |
| 28 | + options = rtc.TrackPublishOptions() |
| 29 | + options.source = rtc.TrackSource.SOURCE_MICROPHONE |
| 30 | + |
| 31 | + await job.connect(auto_subscribe=AutoSubscribe.SUBSCRIBE_NONE) |
| 32 | + publication = await job.room.local_participant.publish_track(track, options) |
| 33 | + await publication.wait_for_subscription() |
| 34 | + |
| 35 | + stream = tts.stream() |
| 36 | + |
| 37 | + async def _playback_task(): |
| 38 | + async for audio in stream: |
| 39 | + await source.capture_frame(audio.frame) |
| 40 | + |
| 41 | + task = asyncio.create_task(_playback_task()) |
| 42 | + |
| 43 | + text = "Hello from Neuphonic. You have just successfully run the example!" |
| 44 | + |
| 45 | + # split into two word chunks to simulate LLM streaming |
| 46 | + words = text.split() |
| 47 | + for i in range(0, len(words), 2): |
| 48 | + chunk = " ".join(words[i : i + 2]) |
| 49 | + if chunk: |
| 50 | + logger.info(f'pushing chunk: "{chunk} "') |
| 51 | + stream.push_text(chunk + " ") |
| 52 | + |
| 53 | + # Mark end of input segment |
| 54 | + stream.flush() |
| 55 | + stream.end_input() |
| 56 | + await asyncio.gather(task) |
| 57 | + |
| 58 | + |
| 59 | +if __name__ == "__main__": |
| 60 | + cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint)) |
0 commit comments