VocalNode / main.py
whynotasif's picture
Upload 2 files
52a4da2 verified
Raw History Blame Contribute Delete
3.29 kB
import os
import shutil
import tempfile
import speech_recognition as sr
from fastapi import FastAPI, UploadFile, File, Form
from pydub import AudioSegment
from pathlib import Path
from typing import Optional
app = FastAPI(title="VocalizeAPI")
# --- LINUX FFMPEG FIX ---
# On some HF containers, we need to explicitly tell pydub where ffmpeg is
if shutil.which("ffmpeg"):
AudioSegment.converter = shutil.which("ffmpeg")
def get_audio_info(file_path):
"""Returns size in MB and duration in seconds."""
size_mb = os.path.getsize(file_path) / (1024 * 1024)
audio = AudioSegment.from_file(file_path)
duration_sec = len(audio) / 1000.0
return size_mb, duration_sec
@app.post("/audio-to-text")
async def audio_to_text(
file: UploadFile = File(...),
lang: Optional[str] = Form(None)
):
temp_dir = tempfile.mkdtemp()
# Ensure filename exists to avoid suffix errors
filename = file.filename if file.filename else "input.ogg"
input_ext = Path(filename).suffix.lower() or ".ogg"
input_path = os.path.join(temp_dir, f"input{input_ext}")
wav_path = os.path.join(temp_dir, "converted.wav")
try:
# 1. Save uploaded file
with open(input_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
# 2. Convert to WAV (Standardized for Google)
audio = AudioSegment.from_file(input_path)
audio = audio.set_channels(1).set_frame_rate(16000)
audio.export(wav_path, format="wav")
target_path = wav_path
# 3. Validate
size_mb, duration = get_audio_info(target_path)
if duration > 60:
return {"status": False, "error": "File Rejected: It's longer than 60s.", "result": ""}
elif size_mb > 10:
return {"status": False, "error": "Error: File is too large (>10MB).", "result": ""}
# 4. Transcribe
r = sr.Recognizer()
with sr.AudioFile(target_path) as source:
r.adjust_for_ambient_noise(source, duration=0.5)
audio_data = r.record(source)
try:
# Use provided lang if it exists and isn't just whitespace
actual_lang = lang.strip() if (lang and lang.strip()) else None
if actual_lang:
text = r.recognize_google(audio_data, language=actual_lang)
else:
text = r.recognize_google(audio_data)
return {"status": True, "error": None, "result": text}
except sr.UnknownValueError:
return {"status": False, "error": "I could not understand the audio (Low quality or silent).", "result": ""}
except sr.RequestError:
return {"status": False, "error": "API-Key Error: Google limit reached.", "result": ""}
except Exception as e:
print(f"Server Log Error: {e}")
return {"status": False, "error": f"System Error: {str(e)}", "result": ""}
finally:
# 5. Cleanup
shutil.rmtree(temp_dir, ignore_errors=True)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860)