mirror of
https://github.com/HumanAIGC-Engineering/gradio-webrtc.git
synced 2026-02-04 17:39:23 +08:00
Set border radius (#84)
Co-authored-by: Freddy Boulton <freddyboulton@hf-freddy.local>
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -17,4 +17,5 @@ demo/scratch
|
||||
.vscode
|
||||
.DS_Store
|
||||
test/
|
||||
.venv*
|
||||
.venv*
|
||||
.env
|
||||
@@ -42,6 +42,8 @@ class UIArgs(TypedDict):
|
||||
"""Color of the icon button. Default is var(--color-accent) of the demo theme."""
|
||||
pulse_color: NotRequired[str]
|
||||
"""Color of the pulse animation. Default is var(--color-accent) of the demo theme."""
|
||||
icon_radius: NotRequired[int]
|
||||
"""Border radius of the icon button expressed as a percentage of the button size. Default is 50%."""
|
||||
|
||||
|
||||
class Stream(WebRTCConnectionMixin):
|
||||
@@ -322,6 +324,7 @@ class Stream(WebRTCConnectionMixin):
|
||||
icon=ui_args.get("icon"),
|
||||
icon_button_color=ui_args.get("icon_button_color"),
|
||||
pulse_color=ui_args.get("pulse_color"),
|
||||
icon_radius=ui_args.get("icon_radius"),
|
||||
)
|
||||
for component in additional_output_components:
|
||||
if component not in same_components:
|
||||
@@ -358,6 +361,10 @@ class Stream(WebRTCConnectionMixin):
|
||||
rtc_configuration=self.rtc_configuration,
|
||||
mode="send-receive",
|
||||
modality="audio",
|
||||
icon=ui_args.get("icon"),
|
||||
icon_button_color=ui_args.get("icon_button_color"),
|
||||
pulse_color=ui_args.get("pulse_color"),
|
||||
icon_radius=ui_args.get("icon_radius"),
|
||||
)
|
||||
for component in additional_input_components:
|
||||
if component not in same_components:
|
||||
@@ -400,6 +407,7 @@ class Stream(WebRTCConnectionMixin):
|
||||
icon=ui_args.get("icon"),
|
||||
icon_button_color=ui_args.get("icon_button_color"),
|
||||
pulse_color=ui_args.get("pulse_color"),
|
||||
icon_radius=ui_args.get("icon_radius"),
|
||||
)
|
||||
for component in additional_input_components:
|
||||
if component not in same_components:
|
||||
@@ -443,6 +451,7 @@ class Stream(WebRTCConnectionMixin):
|
||||
icon=ui_args.get("icon"),
|
||||
icon_button_color=ui_args.get("icon_button_color"),
|
||||
pulse_color=ui_args.get("pulse_color"),
|
||||
icon_radius=ui_args.get("icon_radius"),
|
||||
)
|
||||
for component in additional_input_components:
|
||||
if component not in same_components:
|
||||
@@ -552,6 +561,7 @@ class Stream(WebRTCConnectionMixin):
|
||||
port: int = 8000,
|
||||
**kwargs,
|
||||
):
|
||||
import atexit
|
||||
import secrets
|
||||
import threading
|
||||
import time
|
||||
@@ -563,7 +573,6 @@ class Stream(WebRTCConnectionMixin):
|
||||
from gradio.networking import setup_tunnel
|
||||
from gradio.tunneling import CURRENT_TUNNELS
|
||||
from huggingface_hub import get_token
|
||||
import atexit
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import asyncio
|
||||
import fractions
|
||||
import functools
|
||||
import inspect
|
||||
import io
|
||||
import json
|
||||
import logging
|
||||
import tempfile
|
||||
import traceback
|
||||
from contextvars import ContextVar
|
||||
from typing import Any, Callable, Literal, Protocol, TypedDict, cast
|
||||
import functools
|
||||
import traceback
|
||||
import inspect
|
||||
|
||||
import av
|
||||
import numpy as np
|
||||
from numpy.typing import NDArray
|
||||
|
||||
@@ -87,6 +87,7 @@ class WebRTC(Component, WebRTCConnectionMixin):
|
||||
icon: str | None = None,
|
||||
icon_button_color: str | None = None,
|
||||
pulse_color: str | None = None,
|
||||
icon_radius: int | None = None,
|
||||
button_labels: dict | None = None,
|
||||
):
|
||||
"""
|
||||
@@ -119,6 +120,7 @@ class WebRTC(Component, WebRTCConnectionMixin):
|
||||
icon_button_color: Color of the icon button. Default is var(--color-accent) of the demo theme.
|
||||
pulse_color: Color of the pulse animation. Default is var(--color-accent) of the demo theme.
|
||||
button_labels: Text to display on the audio or video start, stop, waiting buttons. Dict with keys "start", "stop", "waiting" mapping to the text to display on the buttons.
|
||||
icon_radius: Border radius of the icon button expressed as a percentage of the button size. Default is 50%
|
||||
"""
|
||||
self.time_limit = time_limit
|
||||
self.height = height
|
||||
@@ -129,6 +131,7 @@ class WebRTC(Component, WebRTCConnectionMixin):
|
||||
self.mode = mode
|
||||
self.modality = modality
|
||||
self.icon_button_color = icon_button_color
|
||||
self.icon_radius = icon_radius
|
||||
self.pulse_color = pulse_color
|
||||
self.rtp_params = rtp_params or {}
|
||||
self.button_labels = {
|
||||
|
||||
@@ -149,14 +149,14 @@ class WebRTCConnectionMixin:
|
||||
|
||||
if isinstance(self.event_handler, StreamHandlerBase):
|
||||
handler = self.event_handler.copy()
|
||||
handler.emit = webrtc_error_handler(handler.emit)
|
||||
handler.receive = webrtc_error_handler(handler.receive)
|
||||
handler.start_up = webrtc_error_handler(handler.start_up)
|
||||
handler.shutdown = webrtc_error_handler(handler.shutdown)
|
||||
handler.emit = webrtc_error_handler(handler.emit) # type: ignore
|
||||
handler.receive = webrtc_error_handler(handler.receive) # type: ignore
|
||||
handler.start_up = webrtc_error_handler(handler.start_up) # type: ignore
|
||||
handler.shutdown = webrtc_error_handler(handler.shutdown) # type: ignore
|
||||
if hasattr(handler, "video_receive"):
|
||||
handler.video_receive = webrtc_error_handler(handler.video_receive)
|
||||
handler.video_receive = webrtc_error_handler(handler.video_receive) # type: ignore
|
||||
if hasattr(handler, "video_emit"):
|
||||
handler.video_emit = webrtc_error_handler(handler.video_emit)
|
||||
handler.video_emit = webrtc_error_handler(handler.video_emit) # type: ignore
|
||||
else:
|
||||
handler = webrtc_error_handler(cast(Callable, self.event_handler))
|
||||
|
||||
|
||||
@@ -5,16 +5,16 @@ import time
|
||||
from io import BytesIO
|
||||
|
||||
import gradio as gr
|
||||
from gradio.utils import get_space
|
||||
import numpy as np
|
||||
from google import genai
|
||||
from dotenv import load_dotenv
|
||||
from fastrtc import (
|
||||
AsyncAudioVideoStreamHandler,
|
||||
Stream,
|
||||
get_twilio_turn_credentials,
|
||||
WebRTC,
|
||||
get_twilio_turn_credentials,
|
||||
)
|
||||
from google import genai
|
||||
from gradio.utils import get_space
|
||||
from PIL import Image
|
||||
|
||||
load_dotenv()
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
export let icon: string | undefined = undefined;
|
||||
export let icon_button_color: string = "var(--color-accent)";
|
||||
export let pulse_color: string = "var(--color-accent)";
|
||||
export let icon_radius: number = 50;
|
||||
|
||||
const on_change_cb = (msg: "change" | "tick" | any) => {
|
||||
if (
|
||||
@@ -124,6 +125,7 @@
|
||||
{icon}
|
||||
{icon_button_color}
|
||||
{pulse_color}
|
||||
{icon_radius}
|
||||
i18n={gradio.i18n}
|
||||
on:tick={() => gradio.dispatch("tick")}
|
||||
on:error={({ detail }) => gradio.dispatch("error", detail)}
|
||||
@@ -178,6 +180,7 @@
|
||||
{icon}
|
||||
{reject_cb}
|
||||
{icon_button_color}
|
||||
{icon_radius}
|
||||
{pulse_color}
|
||||
{button_labels}
|
||||
on:tick={() => gradio.dispatch("tick")}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
export let icon_button_color: string = "var(--color-accent)";
|
||||
export let pulse_color: string = "var(--color-accent)";
|
||||
export let pending: boolean = false;
|
||||
export let icon_radius: number = 50;
|
||||
|
||||
let audioContext: AudioContext;
|
||||
let analyser: AnalyserNode;
|
||||
@@ -34,6 +35,7 @@
|
||||
});
|
||||
|
||||
function setupAudioContext() {
|
||||
// @ts-ignore
|
||||
audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
||||
analyser = audioContext.createAnalyser();
|
||||
const source = audioContext.createMediaStreamSource(
|
||||
@@ -58,6 +60,7 @@
|
||||
);
|
||||
for (let i = 0; i < bars.length; i++) {
|
||||
const barHeight = (dataArray[i] / 255) * 2;
|
||||
// @ts-ignore
|
||||
bars[i].style.transform = `scaleY(${Math.max(0.1, barHeight)})`;
|
||||
}
|
||||
|
||||
@@ -78,6 +81,7 @@
|
||||
{pulse_color}
|
||||
{icon}
|
||||
{icon_button_color}
|
||||
{icon_radius}
|
||||
{audio_source_callback}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
export let icon: string | undefined = undefined;
|
||||
export let icon_button_color: string = "var(--color-accent)";
|
||||
export let pulse_color: string = "var(--color-accent)";
|
||||
export let icon_radius: number = 50;
|
||||
export let button_labels: { start: string; stop: string; waiting: string };
|
||||
let pending = false;
|
||||
|
||||
@@ -291,6 +292,7 @@
|
||||
{icon_button_color}
|
||||
{pulse_color}
|
||||
{pending}
|
||||
{icon_radius}
|
||||
/>
|
||||
<StreamingBar time_limit={_time_limit} />
|
||||
<div class="button-wrap" class:pulse={stopword_recognized}>
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
{icon_button_color}
|
||||
{pulse_color}
|
||||
{button_labels}
|
||||
{icon_radius}
|
||||
on:error
|
||||
on:start_recording
|
||||
on:stop_recording
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
export let icon: string | ComponentType = undefined;
|
||||
export let icon_button_color: string = "var(--color-accent)";
|
||||
export let pulse_color: string = "var(--color-accent)";
|
||||
export let icon_radius: number = 50;
|
||||
|
||||
let audioContext: AudioContext;
|
||||
let analyser: AnalyserNode;
|
||||
@@ -27,6 +28,7 @@
|
||||
});
|
||||
|
||||
function setupAudioContext() {
|
||||
// @ts-ignore
|
||||
audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
||||
analyser = audioContext.createAnalyser();
|
||||
const source = audioContext.createMediaStreamSource(
|
||||
@@ -77,7 +79,12 @@
|
||||
style:background={icon_button_color}
|
||||
>
|
||||
{#if typeof icon === "string"}
|
||||
<img src={icon} alt="Audio visualization icon" class="icon-image" />
|
||||
<img
|
||||
src={icon}
|
||||
alt="Audio visualization icon"
|
||||
class="icon-image"
|
||||
style:border-radius={`${icon_radius}%`}
|
||||
/>
|
||||
{:else if icon === undefined}
|
||||
<div></div>
|
||||
{:else}
|
||||
@@ -123,7 +130,6 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.pulse-ring {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
export let icon: string | undefined = undefined;
|
||||
export let icon_button_color: string = "var(--color-accent)";
|
||||
export let pulse_color: string = "var(--color-accent)";
|
||||
export let icon_radius: number = 50;
|
||||
|
||||
export let server: {
|
||||
offer: (body: any) => Promise<any>;
|
||||
@@ -65,6 +66,7 @@
|
||||
});
|
||||
let stream = null;
|
||||
const timeoutId = setTimeout(() => {
|
||||
// @ts-ignore
|
||||
on_change_cb({ type: "connection_timeout" });
|
||||
}, 5000);
|
||||
|
||||
@@ -120,6 +122,7 @@
|
||||
{icon}
|
||||
{icon_button_color}
|
||||
{pulse_color}
|
||||
{icon_radius}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -8,7 +8,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "fastrtc"
|
||||
version = "0.0.5.post2"
|
||||
version = "0.0.6"
|
||||
description = "The realtime communication library for Python"
|
||||
readme = "README.md"
|
||||
license = "apache-2.0"
|
||||
@@ -83,3 +83,4 @@ packages = ["/backend/fastrtc"]
|
||||
|
||||
[tool.ruff]
|
||||
target-version = "py310"
|
||||
extend-exclude = ["demo/phonic_chat"]
|
||||
|
||||
Reference in New Issue
Block a user