mirror of
https://github.com/R0m1k3/LiveFlow.git
synced 2026-10-12 01:37:29 +02:00
- docker-compose : Caddy (HTTPS local) + app FastAPI + Qwen3-ASR via vLLM (GPU) - Backend : WebSocket audio, segmentation VAD (WebRTC), appel ASR compatible OpenAI, stockage SQLite, exports TXT/MD/SRT/JSON - Frontend : capture micro (AudioWorklet, rééchantillonnage 16 kHz), transcription live, historique des réunions, copie et téléchargement - README : démarrage, prérequis GPU, changement de moteur ASR https://claude.ai/code/session_01YHMp3EKzr4s6o8w1ygxuUe
43 lines
1.3 KiB
JavaScript
43 lines
1.3 KiB
JavaScript
// Rééchantillonne le micro (fréquence native du navigateur, ex. 48 kHz)
|
|
// vers du PCM Int16 mono 16 kHz, attendu par le serveur.
|
|
class PCMDownsampler extends AudioWorkletProcessor {
|
|
constructor() {
|
|
super();
|
|
this.targetRate = 16000;
|
|
this.ratio = sampleRate / this.targetRate;
|
|
this.buffer = new Float32Array(0);
|
|
this.readPos = 0;
|
|
}
|
|
|
|
process(inputs) {
|
|
const input = inputs[0] && inputs[0][0];
|
|
if (!input) return true;
|
|
|
|
const buf = new Float32Array(this.buffer.length + input.length);
|
|
buf.set(this.buffer);
|
|
buf.set(input, this.buffer.length);
|
|
|
|
const outLen = Math.floor((buf.length - 1 - this.readPos) / this.ratio);
|
|
if (outLen > 0) {
|
|
const out = new Int16Array(outLen);
|
|
let pos = this.readPos;
|
|
for (let i = 0; i < outLen; i++) {
|
|
const i0 = Math.floor(pos);
|
|
const frac = pos - i0;
|
|
const s = buf[i0] * (1 - frac) + buf[i0 + 1] * frac;
|
|
out[i] = Math.max(-32768, Math.min(32767, Math.round(s * 32767)));
|
|
pos += this.ratio;
|
|
}
|
|
this.readPos = pos;
|
|
this.port.postMessage(out.buffer, [out.buffer]);
|
|
}
|
|
|
|
const keep = Math.floor(this.readPos);
|
|
this.buffer = buf.slice(keep);
|
|
this.readPos -= keep;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
registerProcessor('pcm-downsampler', PCMDownsampler);
|