Spaces:
Running
Running
| import asyncio | |
| import numpy as np | |
| import logging | |
| import warnings | |
| import os | |
| import threading | |
| warnings.filterwarnings("ignore") | |
| os.environ["TOKENIZERS_PARALLELISM"] = "false" | |
| from fastapi import FastAPI, WebSocket, WebSocketDisconnect | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from asr import ASRPipeline | |
| logging.basicConfig(level=logging.INFO) | |
| app = FastAPI() | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| pipeline = ASRPipeline() | |
| def root(): | |
| return {"status": "CaptionAI v2 running — Whisper ONNX + Groq hybrid"} | |
| async def websocket_endpoint(websocket: WebSocket): | |
| await websocket.accept() | |
| print("=" * 50) | |
| print("Client connected") | |
| print("=" * 50) | |
| loop = asyncio.get_event_loop() | |
| caption_queue = asyncio.Queue() | |
| async def send_results(): | |
| while True: | |
| text = await caption_queue.get() | |
| if text is None: | |
| break | |
| try: | |
| await websocket.send_text(text) | |
| except Exception: | |
| break | |
| sender = asyncio.create_task(send_results()) | |
| try: | |
| while True: | |
| data = await websocket.receive_bytes() | |
| audio_chunk = np.frombuffer(data, dtype=np.float32) | |
| def process(chunk=audio_chunk): | |
| result = pipeline.transcribe_chunk(chunk) | |
| if result: | |
| asyncio.run_coroutine_threadsafe( | |
| caption_queue.put(result), | |
| loop | |
| ) | |
| threading.Thread(target=process, daemon=True).start() | |
| except WebSocketDisconnect: | |
| pipeline.stop() | |
| await caption_queue.put(None) | |
| await sender | |
| print("=" * 50) | |
| print("Client disconnected") | |
| print("=" * 50) | |
| except Exception as e: | |
| print(f"Error: {e}") | |
| pipeline.stop() | |
| await caption_queue.put(None) | |
| await websocket.close() | |