faster-whisper (small.en, GPU+CPU fallback) on CT 102 → POST /api/voice/transcribe (multer→whisper client) → mic in the bubble records (MediaRecorder), uploads, drops the transcript into the input to review-and-send. Infra scripts in deploy/whisper/. Retention (P2b) next. NOTE: mic needs a secure context (the https domain), not the LAN IP. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
23 lines
988 B
JavaScript
23 lines
988 B
JavaScript
// Thin client for the local faster-whisper service on CT 102 (the Ollama box).
|
|
// GPU with CPU fallback lives in the service itself; here we just POST the audio
|
|
// buffer and return the transcript. LAN-only endpoint.
|
|
const WHISPER_URL = process.env.WHISPER_URL || 'http://192.168.1.185:8001';
|
|
|
|
export async function transcribe(buffer, filename = 'clip.webm', mime = 'audio/webm') {
|
|
const fd = new FormData();
|
|
fd.append('file', new Blob([buffer], { type: mime }), filename);
|
|
const res = await fetch(`${WHISPER_URL}/transcribe`, {
|
|
method: 'POST', body: fd, signal: AbortSignal.timeout(120000)
|
|
});
|
|
if (!res.ok) throw new Error(`whisper ${res.status}`);
|
|
const j = await res.json();
|
|
return { text: (j.text || '').trim(), duration: j.duration, device: j.device };
|
|
}
|
|
|
|
export async function health() {
|
|
try {
|
|
const res = await fetch(`${WHISPER_URL}/health`, { signal: AbortSignal.timeout(5000) });
|
|
return res.ok ? await res.json() : null;
|
|
} catch { return null; }
|
|
}
|