Add UmbraAudio Voice Studio branding to web demo (icon + favicon)
Some checks failed
Close and lock inactive threads / manage-inactive (push) Has been cancelled
Some checks failed
Close and lock inactive threads / manage-inactive (push) Has been cancelled
Embeds the UmbraAudio logo as a data URI in the Gradio header and wires the repo logo as the browser favicon. Cosmetic only; no TTS behavior changes.
This commit is contained in:
BIN
assets/logo.png
Normal file
BIN
assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
@@ -18,9 +18,11 @@ A gradio demo for Qwen3 TTS models.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import base64
|
||||
import os
|
||||
import tempfile
|
||||
from dataclasses import asdict
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
import gradio as gr
|
||||
@@ -59,6 +61,31 @@ def _maybe(v):
|
||||
return v if v is not None else gr.update()
|
||||
|
||||
|
||||
def _find_icon() -> Optional[Path]:
|
||||
candidates = [
|
||||
Path(os.environ.get("UMBRA_AUDIO_ICON", "")) if os.environ.get("UMBRA_AUDIO_ICON") else None,
|
||||
Path("/Volumes/1TB_APL_Storage/UmbraAudio/UmbraAudio_icon.png"),
|
||||
Path(__file__).resolve().parents[2] / "assets" / "logo.png",
|
||||
Path("/Volumes/1TB_APL_Storage/UmbraAudio/UmbraAudio_icon.jpeg"),
|
||||
]
|
||||
for c in candidates:
|
||||
if c is not None and c.is_file():
|
||||
return c
|
||||
return None
|
||||
|
||||
|
||||
def _icon_data_uri() -> Optional[str]:
|
||||
icon = _find_icon()
|
||||
if icon is None:
|
||||
return None
|
||||
try:
|
||||
data = base64.b64encode(icon.read_bytes()).decode("ascii")
|
||||
mime = "image/png" if icon.suffix.lower() == ".png" else "image/jpeg"
|
||||
return f"data:{mime};base64,{data}"
|
||||
except OSError:
|
||||
return None
|
||||
|
||||
|
||||
def build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="qwen-tts-demo",
|
||||
@@ -168,6 +195,18 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
return parser
|
||||
|
||||
|
||||
def _find_favicon() -> Optional[Path]:
|
||||
for name in ("UmbraAudio_icon.png", "logo.png"):
|
||||
p = Path(__file__).resolve().parents[3] / name
|
||||
if p.is_file():
|
||||
return p
|
||||
alt = Path("/Volumes/1TB_APL_Storage/UmbraAudio") / name
|
||||
if alt.is_file():
|
||||
return alt
|
||||
icon = _find_icon()
|
||||
return icon if icon is not None and icon.suffix.lower() in (".png", ".gif", ".ico") else None
|
||||
|
||||
|
||||
def _resolve_checkpoint(args: argparse.Namespace) -> str:
|
||||
ckpt = args.checkpoint or args.checkpoint_pos
|
||||
if not ckpt:
|
||||
@@ -275,6 +314,23 @@ def build_demo(tts: Qwen3TTSModel, ckpt: str, gen_kwargs_default: Dict[str, Any]
|
||||
css = ".gradio-container {max-width: none !important;}"
|
||||
|
||||
with gr.Blocks(theme=theme, css=css) as demo:
|
||||
icon_uri = _icon_data_uri()
|
||||
if icon_uri:
|
||||
with gr.Row():
|
||||
with gr.Column(scale=1, min_width=120):
|
||||
gr.HTML(
|
||||
f'<img src="{icon_uri}" alt="UmbraAudio" '
|
||||
'style="max-height:96px; display:block; margin:0 auto;">'
|
||||
)
|
||||
with gr.Column(scale=4):
|
||||
gr.Markdown(
|
||||
f"""
|
||||
# UmbraAudio Voice Studio
|
||||
**Checkpoint:** `{ckpt}`
|
||||
**Model Type:** `{model_kind}`
|
||||
"""
|
||||
)
|
||||
else:
|
||||
gr.Markdown(
|
||||
f"""
|
||||
# Qwen3 TTS Demo
|
||||
@@ -621,6 +677,9 @@ def main(argv=None) -> int:
|
||||
share=args.share,
|
||||
ssl_verify=True if args.ssl_verify else False,
|
||||
)
|
||||
favicon = _find_favicon()
|
||||
if favicon is not None:
|
||||
launch_kwargs["favicon_path"] = str(favicon)
|
||||
if args.ssl_certfile is not None:
|
||||
launch_kwargs["ssl_certfile"] = args.ssl_certfile
|
||||
if args.ssl_keyfile is not None:
|
||||
|
||||
Reference in New Issue
Block a user