gooya-asr / app.py
navidved's picture
Update app.py
bda9ee3 verified
raw
history blame
4.81 kB
import gradio as gr
import requests, os, time, pathlib
ASR_API_URL = os.getenv("ASR_API_URL")
AUTH_TOKEN = os.getenv("AUTH_TOKEN")
# ---------- کمکى: استخراج مسیر واقعی فایل ----------
def extract_path(audio_value):
"""
audio_value می‌تواند None، رشته یا دیکشنری باشد.
خروجی: مسیر فایل یا None
"""
if not audio_value:
return None
if isinstance(audio_value, dict):
return audio_value.get("path") # گرادیو ≥ 4
# برای سازگاری با نسخه‌های قدیم‌تر که str برمی‌گردانند
return audio_value if isinstance(audio_value, (str, pathlib.Path)) else None
# ---------- پردازش ----------
def transcribe_audio(audio_value):
file_path = extract_path(audio_value)
if not file_path:
return "❌ فایل صوتی هنوز آماده نیست.", ""
if not ASR_API_URL or not AUTH_TOKEN:
return "❌ Error: ASR_API_URL or AUTH_TOKEN is not set.", ""
headers = {
"accept": "application/json",
"Authorization": f"Bearer {AUTH_TOKEN}",
}
start = time.time()
try:
with open(file_path, "rb") as f:
files = {"file": (os.path.basename(file_path), f, "audio/mpeg")}
response = requests.post(ASR_API_URL, headers=headers, files=files)
except Exception as e:
return f"❌ Error: {e}", ""
elapsed = time.time() - start
if response.status_code == 200:
data = response.json()
txt = data.get("transcription", "No transcription returned.")
elapsed = data.get("time", elapsed)
return txt, f"{elapsed:.2f} seconds"
return f"❌ Error {response.status_code}: {response.text}", ""
# ---------- رابط کاربری ----------
CUSTOM_CSS = """
#gooya-title {color:white; background:linear-gradient(90deg,#224CA5 0%,#2CD8D5 100%);
border-radius:12px;padding:20px 10px;margin-bottom:12px;}
.gooya-badge {display:inline-block;background:#224CA5;color:#fff;border-radius:16px;
padding:6px 16px;font-size:0.97rem;margin-top:4px;}
"""
with gr.Blocks(css=CUSTOM_CSS) as demo:
gr.HTML("""
<div id="gooya-title">
<h1 style='margin-bottom:10px;font-weight:800;font-size:2rem;'>Gooya ASR
<span style="font-size:1.1rem;font-weight:400;opacity:0.8;'>v1.4</span></h1>
<p style='font-size:1.12rem;margin-bottom:2px;'>High-performance Persian Speech-to-Text</p>
<p style='font-size:0.98rem;color:#c6e8fa'>Upload or record a Persian audio file (max 30s) and instantly receive the transcription.</p>
</div>
""")
with gr.Row():
with gr.Column():
audio = gr.Audio(
label="Audio Input (Upload or record, up to 30s)",
type="filepath",
sources=["upload", "microphone"],
show_label=True,
)
with gr.Column():
inf_time_lbl = gr.Label(label="⏱️ Processing Time", elem_classes="gooya-badge")
transcription = gr.Textbox(
label="📝 Transcription",
lines=5,
show_copy_button=True,
placeholder="The transcription will appear here...",
elem_id="gooya-textbox",
)
with gr.Row():
submit_btn = gr.Button("Transcribe", variant="primary", interactive=False)
clear_btn = gr.Button("Clear", variant="secondary")
# ---------- فعال / غیرفعال کردن دکمه ----------
def toggle_btn(audio_value):
return gr.Button.update(interactive=bool(extract_path(audio_value)))
# بعد از آپلود فایل
audio.change(toggle_btn, inputs=audio, outputs=submit_btn, queue=False)
# بعد از پایان ضبط میکروفون
audio.stop_recording(toggle_btn, inputs=audio, outputs=submit_btn, queue=False)
# ---------- پردازش ----------
submit_btn.click(
transcribe_audio,
inputs=audio,
outputs=[transcription, inf_time_lbl],
).then(
lambda: gr.Button.update(interactive=False),
None,
submit_btn,
queue=False,
)
# ---------- پاک‌کردن ----------
def clear_all():
return (
"", # متن
"", # زمان
gr.Audio.update(value=None), # پاک کردن کامپوننت Audio
gr.Button.update(interactive=False), # غیر فعال کردن دکمه
)
clear_btn.click(
clear_all,
None,
[transcription, inf_time_lbl, audio, submit_btn],
queue=False,
)
demo.launch()