From 02aef9da581f00cc82e43444ba0d7ea15e7023c9 Mon Sep 17 00:00:00 2001 From: Freddy Boulton <41651716+freddyaboulton@users.noreply.github.com> Date: Wed, 23 Apr 2025 16:01:54 -0400 Subject: [PATCH] Add ability to Hide Title in Built-in UI + llama 4 cartesia tweaks (#299) * merge title * Fix --- backend/fastrtc/__init__.py | 7 +- backend/fastrtc/stream.py | 164 +++++++++++---------- backend/fastrtc/text_to_speech/__init__.py | 8 +- backend/fastrtc/text_to_speech/tts.py | 5 +- demo/talk_to_llama4/AV_Huggy.png | Bin 0 -> 46888 bytes demo/talk_to_llama4/app.py | 44 ++++-- 6 files changed, 131 insertions(+), 97 deletions(-) create mode 100644 demo/talk_to_llama4/AV_Huggy.png diff --git a/backend/fastrtc/__init__.py b/backend/fastrtc/__init__.py index 43f61ec..2e08399 100644 --- a/backend/fastrtc/__init__.py +++ b/backend/fastrtc/__init__.py @@ -17,7 +17,11 @@ from .reply_on_pause import AlgoOptions, ReplyOnPause from .reply_on_stopwords import ReplyOnStopWords from .speech_to_text import MoonshineSTT, get_stt_model from .stream import Stream, UIArgs -from .text_to_speech import KokoroTTSOptions, get_tts_model +from .text_to_speech import ( + CartesiaTTSOptions, + KokoroTTSOptions, + get_tts_model, +) from .tracks import ( AsyncAudioVideoStreamHandler, AsyncStreamHandler, @@ -87,4 +91,5 @@ __all__ = [ "VideoStreamHandler", "CloseStream", "get_current_context", + "CartesiaTTSOptions", ] diff --git a/backend/fastrtc/stream.py b/backend/fastrtc/stream.py index d1b53ac..1a2acdc 100644 --- a/backend/fastrtc/stream.py +++ b/backend/fastrtc/stream.py @@ -59,6 +59,8 @@ class UIArgs(TypedDict): If "submit", the input will be sent when the submit event is triggered by the user. If "change", the input will be sent whenever the user changes the input value. """ + hide_title: NotRequired[bool] + """If True, the title and subtitle will not be displayed.""" class Stream(WebRTCConnectionMixin): @@ -339,21 +341,22 @@ class Stream(WebRTCConnectionMixin): same_components.append(component) if self.modality == "video" and self.mode == "receive": with gr.Blocks() as demo: - gr.HTML( - f""" -

- {ui_args.get("title", "Video Streaming (Powered by FastRTC ⚡️)")} -

- """ - ) - if ui_args.get("subtitle"): - gr.Markdown( + if not ui_args.get("hide_title"): + gr.HTML( f""" -
- {ui_args.get("subtitle")} -
- """ +

+ {ui_args.get("title", "Video Streaming (Powered by FastRTC ⚡️)")} +

+ """ ) + if ui_args.get("subtitle"): + gr.Markdown( + f""" +
+ {ui_args.get("subtitle")} +
+ """ + ) with gr.Row(): with gr.Column(): if additional_input_components: @@ -391,21 +394,22 @@ class Stream(WebRTCConnectionMixin): ) elif self.modality == "video" and self.mode == "send": with gr.Blocks() as demo: - gr.HTML( - f""" -

- {ui_args.get("title", "Video Streaming (Powered by FastRTC ⚡️)")} -

- """ - ) - if ui_args.get("subtitle"): - gr.Markdown( + if not ui_args.get("hide_title"): + gr.HTML( f""" -
- {ui_args.get("subtitle")} -
- """ +

+ {ui_args.get("title", "Video Streaming (Powered by FastRTC ⚡️)")} +

+ """ ) + if ui_args.get("subtitle"): + gr.Markdown( + f""" +
+ {ui_args.get("subtitle")} +
+ """ + ) with gr.Row(): if additional_input_components: with gr.Column(): @@ -494,21 +498,22 @@ class Stream(WebRTCConnectionMixin): ) elif self.modality == "audio" and self.mode == "receive": with gr.Blocks() as demo: - gr.HTML( - f""" -

- {ui_args.get("title", "Audio Streaming (Powered by FastRTC ⚡️)")} -

- """ - ) - if ui_args.get("subtitle"): - gr.Markdown( + if not ui_args.get("hide_title"): + gr.HTML( f""" -
- {ui_args.get("subtitle")} -
- """ +

+ {ui_args.get("title", "Audio Streaming (Powered by FastRTC ⚡️)")} +

+ """ ) + if ui_args.get("subtitle"): + gr.Markdown( + f""" +
+ {ui_args.get("subtitle")} +
+ """ + ) with gr.Row(): with gr.Column(): for component in additional_input_components: @@ -549,21 +554,22 @@ class Stream(WebRTCConnectionMixin): ) elif self.modality == "audio" and self.mode == "send": with gr.Blocks() as demo: - gr.HTML( - f""" -

- {ui_args.get("title", "Audio Streaming (Powered by FastRTC ⚡️)")} -

- """ - ) - if ui_args.get("subtitle"): - gr.Markdown( + if not ui_args.get("hide_title"): + gr.HTML( f""" -
- {ui_args.get("subtitle")} -
- """ +

+ {ui_args.get("title", "Audio Streaming (Powered by FastRTC ⚡️)")} +

+ """ ) + if ui_args.get("subtitle"): + gr.Markdown( + f""" +
+ {ui_args.get("subtitle")} +
+ """ + ) with gr.Row(): with gr.Column(): with gr.Group(): @@ -604,21 +610,22 @@ class Stream(WebRTCConnectionMixin): ) elif self.modality == "audio" and self.mode == "send-receive": with gr.Blocks() as demo: - gr.HTML( - f""" -

- {ui_args.get("title", "Audio Streaming (Powered by FastRTC ⚡️)")} -

- """ - ) - if ui_args.get("subtitle"): - gr.Markdown( + if not ui_args.get("hide_title"): + gr.HTML( f""" -
- {ui_args.get("subtitle")} -
- """ +

+ {ui_args.get("title", "Audio Streaming (Powered by FastRTC ⚡️)")} +

+ """ ) + if ui_args.get("subtitle"): + gr.Markdown( + f""" +
+ {ui_args.get("subtitle")} +
+ """ + ) with gr.Row(): with gr.Column(): with gr.Group(): @@ -662,21 +669,22 @@ class Stream(WebRTCConnectionMixin): css = """.my-group {max-width: 600px !important; max-height: 600 !important;} .my-column {display: flex !important; justify-content: center !important; align-items: center !important};""" with gr.Blocks(css=css) as demo: - gr.HTML( - f""" -

- {ui_args.get("title", "Audio Video Streaming (Powered by FastRTC ⚡️)")} -

- """ - ) - if ui_args.get("subtitle"): - gr.Markdown( + if not ui_args.get("hide_title"): + gr.HTML( f""" -
- {ui_args.get("subtitle")} -
- """ +

+ {ui_args.get("title", "Audio Video Streaming (Powered by FastRTC ⚡️)")} +

+ """ ) + if ui_args.get("subtitle"): + gr.Markdown( + f""" +
+ {ui_args.get("subtitle")} +
+ """ + ) with gr.Row(): with gr.Column(elem_classes=["my-column"]): with gr.Group(elem_classes=["my-group"]): diff --git a/backend/fastrtc/text_to_speech/__init__.py b/backend/fastrtc/text_to_speech/__init__.py index 2cc082a..0d55538 100644 --- a/backend/fastrtc/text_to_speech/__init__.py +++ b/backend/fastrtc/text_to_speech/__init__.py @@ -1,3 +1,7 @@ -from .tts import KokoroTTSOptions, get_tts_model +from .tts import ( + CartesiaTTSOptions, + KokoroTTSOptions, + get_tts_model, +) -__all__ = ["get_tts_model", "KokoroTTSOptions"] +__all__ = ["get_tts_model", "KokoroTTSOptions", "CartesiaTTSOptions"] diff --git a/backend/fastrtc/text_to_speech/tts.py b/backend/fastrtc/text_to_speech/tts.py index 37743be..f800e4b 100644 --- a/backend/fastrtc/text_to_speech/tts.py +++ b/backend/fastrtc/text_to_speech/tts.py @@ -2,7 +2,7 @@ import asyncio import importlib.util import re from collections.abc import AsyncGenerator, Generator -from dataclasses import dataclass +from dataclasses import dataclass, field from functools import lru_cache from typing import Literal, Protocol, TypeVar @@ -153,10 +153,11 @@ class KokoroTTSModel(TTSModel): break +@dataclass class CartesiaTTSOptions(TTSOptions): voice: str = "71a7ad14-091c-4e8e-a314-022ece01c121" language: str = "en" - emotion: list[str] = [] + emotion: list[str] = field(default_factory=list) cartesia_version: str = "2024-06-10" model: str = "sonic-2" sample_rate: int = 22_050 diff --git a/demo/talk_to_llama4/AV_Huggy.png b/demo/talk_to_llama4/AV_Huggy.png new file mode 100644 index 0000000000000000000000000000000000000000..6a9fb741f3c9050b6d89f898a71c56095b193eaf GIT binary patch literal 46888 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 z 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 + AV Huggy FastRTC + Cartesia TTS = Blazing Fast LLM Audio + + """ + ) + stream.ui.render() + +stream.ui = demo + app = FastAPI() stream.mount(app) @@ -109,9 +121,13 @@ async def _(webrtc_id: str): if __name__ == "__main__": import os + from pathlib import Path if (mode := os.getenv("MODE")) == "UI": - stream.ui.launch(server_port=7860) + stream.ui.launch( + server_port=7860, + allowed_paths=[str((Path(__file__).parent / "AV_Huggy.png").resolve())], + ) elif mode == "PHONE": raise ValueError("Phone mode not supported") else: