Initial commit: VoIdeaAI - voice-first AI idea assistant
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
"""Whisper transcription service for VoIdeaAI.
|
||||
|
||||
Used as fallback when browser Web Speech API fails.
|
||||
Supports OpenAI Whisper API and compatible endpoints.
|
||||
"""
|
||||
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import httpx
|
||||
|
||||
from app.core.config import get_settings
|
||||
|
||||
WHISPER_URL = "https://api.openai.com/v1/audio/transcriptions"
|
||||
|
||||
|
||||
async def transcribe(audio_data: bytes, filename: str = "audio.webm") -> str | None:
|
||||
"""Transcribe audio using Whisper API.
|
||||
|
||||
Args:
|
||||
audio_data: Raw audio bytes
|
||||
filename: Original filename (determines format)
|
||||
|
||||
Returns:
|
||||
Transcribed text or None if failed
|
||||
"""
|
||||
settings = get_settings()
|
||||
|
||||
api_key = settings.openai_api_key or settings.ai_yandex_key or ""
|
||||
if not api_key:
|
||||
return None
|
||||
|
||||
url = WHISPER_URL
|
||||
|
||||
with tempfile.NamedTemporaryFile(delete=False, suffix=Path(filename).suffix) as tmp:
|
||||
tmp.write(audio_data)
|
||||
tmp_path = tmp.name
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||
with open(tmp_path, "rb") as f:
|
||||
resp = await client.post(
|
||||
url,
|
||||
headers={"Authorization": f"Bearer {api_key}"},
|
||||
files={"file": (filename, f, "audio/webm")},
|
||||
data={"model": "whisper-1", "language": "ru"},
|
||||
)
|
||||
if resp.status_code == 200:
|
||||
return resp.json().get("text")
|
||||
return None
|
||||
except Exception:
|
||||
return None
|
||||
finally:
|
||||
Path(tmp_path).unlink(missing_ok=True)
|
||||
Reference in New Issue
Block a user