Subflow / app.py
AliJabbarpour's picture
Update app.py
c092233 verified
Raw History Blame
4.43 kB
import os
import tempfile
import numpy as np
import torch
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.middleware.cors import CORSMiddleware
from faster_whisper import WhisperModel
from df.enhance import enhance, init_df, load_audio, save_audio
from pipeline.postprocess import process
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
print("Loading Whisper model...", flush=True)
model = WhisperModel("large-v3", device="cpu", compute_type="int8")
print("Whisper model ready!")
print("Loading DeepFilterNet model...", flush=True)
df_model, df_state, _ = init_df()
print("DeepFilterNet model ready!")
USE_DEEPFILTERNET = False # برای تست بدون DeepFilterNet، این رو موقتاً False کن
@app.get("/health")
async def health():
return {"status": "ok", "message": "SubFlow backend is running"}
@app.websocket("/transcribe")
async def transcribe(websocket: WebSocket):
await websocket.accept()
tmp_path = None
enhanced_path = None
try:
print("Step 1: 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": "cleaning"})
print("Step 3.5: cleaning audio with DeepFilterNet")
audio_to_transcribe = tmp_path
if USE_DEEPFILTERNET:
await websocket.send_json({"status": "cleaning"})
print("Step 3.5: cleaning audio with DeepFilterNet")
audio_data, _ = load_audio(tmp_path, sr=df_state.sr())
enhanced_audio = enhance(df_model, df_state, audio_data, atten_lim_db=20)
enhanced_path = tmp_path.replace(".wav", "_enhanced.wav")
save_audio(enhanced_path, enhanced_audio, df_state.sr())
audio_to_transcribe = enhanced_path
print(f"Step 3.6: cleaned audio saved to {enhanced_path}")
else:
print("Step 3.5: skipping DeepFilterNet (disabled for A/B test)")
await websocket.send_json({"status": "transcribing"})
print("Step 4: starting transcription")
segments_raw, info = model.transcribe(
audio_to_transcribe,
language="en",
word_timestamps=True,
vad_filter=True,
vad_parameters=dict(
min_silence_duration_ms=500,
speech_pad_ms=200,
threshold=0.1
),
)
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")
for i, seg in enumerate(segments[:5]):
print(f" seg[{i}]: '{seg['text']}' | words={len(seg['words'])} | dur={seg['end']-seg['start']:.2f}s")
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)
if enhanced_path and os.path.exists(enhanced_path):
os.remove(enhanced_path)
try:
await websocket.close()
except Exception:
pass