Add UmbraAudio Voice Studio branding to web demo (icon + favicon)
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:
B.D. Murphy
2026-09-22 19:12:21 -07:00
parent 022e286b98
commit 012e45298d
2 changed files with 62 additions and 3 deletions

BIN
assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -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: