Spaces:
Sleeping
Sleeping
File size: 4,029 Bytes
506fa34 09641fb fc5945f 506fa34 d048c85 506fa34 fc5945f f43d1ba 506fa34 f43d1ba 506fa34 fc5945f 506fa34 0040522 506fa34 43e2088 506fa34 43e2088 506fa34 a5fb12b 506fa34 09641fb 506fa34 0040522 506fa34 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | # app.py
import time
import traceback
from datetime import datetime
import torch
import gradio as gr
import requests
from transformers import pipeline
from transformers.pipelines.audio_utils import ffmpeg_read
# ----------------------------
# Firebase (PUBLIC DB)
# ----------------------------
FIREBASE_URL = "https://speechad-32698-default-rtdb.firebaseio.com"
def firebase_put_transcribe(text: str) -> bool:
"""
Overwrite /transcribe with latest transcription
"""
payload = {
"text": text,
"updated_at": datetime.utcnow().isoformat() + "Z",
"length": len(text),
}
try:
url = f"{FIREBASE_URL}/transcribe.json"
r = requests.put(url, json=payload, timeout=10)
print("Firebase PUT status:", r.status_code)
print("Firebase PUT response:", r.text)
return r.ok
except Exception as e:
print("Firebase PUT exception:", e)
return False
# ----------------------------
# Whisper model
# ----------------------------
MODEL_NAME = "openai/whisper-small"
device = 0 if torch.cuda.is_available() else -1
pipe = pipeline(
"automatic-speech-recognition",
model=MODEL_NAME,
device=device,
chunk_length_s=60,
ignore_warning=True,
)
CHUNK_SEC = 2
OVERLAP_SEC = 0.05
SLEEP_BETWEEN_CHUNKS = 0.01
def merge_overlap(prev: str, new: str, max_words: int = 12) -> str:
if not prev:
return new
pw = prev.split()
nw = new.split()
max_k = min(max_words, len(pw), len(nw))
for k in range(max_k, 0, -1):
if pw[-k:] == nw[:k]:
return " ".join(pw + nw[k:])
return prev + " " + new
# ----------------------------
# Transcription
# ----------------------------
def transcribe_file(filepath: str):
if not filepath:
raise gr.Error("No audio provided")
try:
sr = pipe.feature_extractor.sampling_rate
with open(filepath, "rb") as f:
audio = ffmpeg_read(f.read(), sr)
accumulated = ""
chunk_samples = int(CHUNK_SEC * sr)
overlap_samples = int(OVERLAP_SEC * sr)
for start in range(0, len(audio), chunk_samples):
end = min(len(audio), start + chunk_samples)
chunk = audio[max(0, start - overlap_samples):min(len(audio), end + overlap_samples)]
result = pipe({"array": chunk, "sampling_rate": sr})
text = result.get("text", "").strip()
accumulated = merge_overlap(accumulated, text)
yield accumulated, gr.update(visible=False)
time.sleep(SLEEP_BETWEEN_CHUNKS)
# FINAL WRITE (overwrite)
ok = firebase_put_transcribe(accumulated)
if ok:
yield accumulated, gr.update(
visible=True,
value="""
<div style="text-align:center;margin-top:20px">
<a href="https://nolist-testingspeechwhisper.hf.space"
style="padding:12px 24px;
background:#2563eb;
color:white;
border-radius:8px;
text-decoration:none;
font-weight:600;">
Continue
</a>
</div>
"""
)
else:
yield accumulated, gr.update(
visible=True,
value="<b style='color:red'>Firebase write failed</b>"
)
except Exception as e:
raise gr.Error(f"Transcription failed: {e}\n{traceback.format_exc()}")
# ----------------------------
# Gradio UI
# ----------------------------
with gr.Blocks(title="Record Option") as demo:
gr.Markdown("# Record Option")
audio = gr.Audio(sources=["microphone"], type="filepath")
output = gr.Textbox(lines=12, label="Transcription")
html = gr.HTML(visible=False)
audio.change(transcribe_file, audio, [output, html])
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)
|