Download app.py from SubLabAI/Subflow: direct link, hf CLI and curl.
- Browser
- Download file 2.96 kB
-
https://huggingface.co/spaces/SubLabAI/Subflow/resolve/2cf7da7289fb6ebf6ccd69342fe4d373a00835b2/app.py
- Command line
-
hf download hf://spaces/SubLabAI/Subflow@2cf7da7289fb6ebf6ccd69342fe4d373a00835b2/app.py
-
curl -L -o app.py https://huggingface.co/spaces/SubLabAI/Subflow/resolve/2cf7da7289fb6ebf6ccd69342fe4d373a00835b2/app.py
2.96 kB
| import os | |
| import tempfile | |
| from fastapi import FastAPI, WebSocket, WebSocketDisconnect | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from faster_whisper import WhisperModel | |
| from pipeline.postprocess import process | |
| app = FastAPI() | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| print("Loading Whisper model...") | |
| model = WhisperModel("large-v3", device="cpu", compute_type="int8") | |
| print("Whisper model ready!") | |
| async def health(): | |
| return {"status": "ok", "message": "SubFlow backend is running"} | |
| async def transcribe(websocket: WebSocket): | |
| await websocket.accept() | |
| tmp_path = None | |
| try: | |
| await websocket.send_json({"status": "connected"}) | |
| print("Step 1: sent connected signal, waiting for bytes") | |
| audio_bytes = await websocket.receive_bytes() | |
| print(f"Step 2: received {len(audio_bytes)} bytes") | |
| await websocket.send_json({"status": "receiving"}) | |
| with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp: | |
| tmp.write(audio_bytes) | |
| tmp_path = tmp.name | |
| print(f"Step 3: saved to {tmp_path}") | |
| await websocket.send_json({"status": "transcribing"}) | |
| print("Step 4: starting transcription") | |
| segments_raw, info = model.transcribe( | |
| tmp_path, | |
| language="en", | |
| word_timestamps=True, | |
| vad_filter=True, | |
| ) | |
| print("Step 5: transcription done") | |
| await websocket.send_json({"status": "processing"}) | |
| segments = [] | |
| for seg in segments_raw: | |
| words = list(seg.words) | |
| if not words: | |
| continue | |
| segments.append({ | |
| "text": seg.text.strip(), | |
| "start": words[0].start, | |
| "end": words[-1].end, | |
| "words": [ | |
| {"word": w.word, "start": w.start, "end": w.end} | |
| for w in words | |
| ], | |
| }) | |
| print(f"Step 6: got {len(segments)} segments") | |
| srt_content = process(segments) | |
| print(f"Step 7: SRT built") | |
| await websocket.send_json({ | |
| "status": "done", | |
| "srt": srt_content, | |
| "language": info.language, | |
| "duration": info.duration, | |
| }) | |
| print("Step 8: done sent!") | |
| except WebSocketDisconnect: | |
| print("WebSocket disconnected by client") | |
| except Exception as e: | |
| print(f"ERROR: {type(e).__name__}: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| try: | |
| await websocket.send_json({"status": "error", "message": str(e)}) | |
| except Exception: | |
| pass | |
| finally: | |
| if tmp_path and os.path.exists(tmp_path): | |
| os.remove(tmp_path) | |
| try: | |
| await websocket.close() | |
| except Exception: | |
| pass |