audio_to_text / app.py
missvector's picture
Upd
51c858c
import os
import tempfile
import shutil
from pathlib import Path
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware
from faster_whisper import WhisperModel
app = FastAPI()
# CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
# Static files
app.mount("/static", StaticFiles(directory="static"), name="static")
print("Loading faster-whisper-tiny...")
model = WhisperModel(
"tiny",
device="cpu",
compute_type="int8"
)
print("Model ready")
@app.get("/", response_class=HTMLResponse)
async def root():
with open("index.html", "r", encoding="utf-8") as f:
return f.read()
@app.post("/transcribe")
async def transcribe_audio(file: UploadFile = File(...)):
tmp_path = None
try:
# Save uploaded file
suffix = Path(file.filename).suffix
with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
shutil.copyfileobj(file.file, tmp)
tmp_path = tmp.name
# Transcribe with faster-whisper
segments, info = model.transcribe(tmp_path, language="ru", beam_size=5)
# Collect all text
text = " ".join([segment.text for segment in segments])
return JSONResponse({"text": text.strip(), "status": "ok"})
except Exception as e:
print(f"Error: {str(e)}")
return JSONResponse(
{"text": f"Error: {str(e)}", "status": "error"},
status_code=500
)
finally:
# Clean up
if tmp_path and Path(tmp_path).exists():
Path(tmp_path).unlink()
await file.close()