Transcription en temps réel

La route WebSocket /v1/ws/transcribe transcrit de courts enregistrements au fil de la parole : vous envoyez l’audio par morceaux, puis vous demandez la transcription du tout.

Offres Pro et Entreprise

La transcription en temps réel est incluse dans les offres Pro et Entreprise. Avec une autre offre, la connexion est refusée avec le code 4029 et un message explicatif (Quotas et tarifs).

Connexion

wss://api.lexiafrik.com/v1/ws/transcribe?api_key=lx_votre_cle

Un navigateur ne peut pas ajouter d’en-tête à une connexion WebSocket : la clé passe donc dans l’adresse (api_key). Gardez-la côté serveur ; ne placez pas une clé dans une page publique.

À la connexion, le serveur répond {"type": "ready", …} quand il est prêt à recevoir l’audio.

Code de fermetureCause
4001Clé API invalide.
4029Offre sans temps réel, ou quota et crédit épuisés.

Protocole

Du client vers le serveur :

MessageEffet
Données binairesAjoutées à la mémoire tampon audio.
Texte transcribeTranscrit tout ce qui a été reçu, puis vide la mémoire tampon.
Texte resetVide la mémoire tampon sans transcrire.
Texte closeFerme proprement la connexion.

Du serveur vers le client, un message JSON dont le champ type vaut :

typeContenu
readyConnexion établie.
transcriptiontext, duration_s, request_id, timestamp et code_switching (répartition des langues détectées dans le texte).
resetMémoire tampon vidée.
errordetail explique le problème (mémoire tampon vide, quota épuisé, audio trop long…).

Format de l’audio

Ce qui est envoyé entre deux commandes transcribe doit former un fichier audio complet et valide (WAV, WebM, MP3, Ogg…), découpé en morceaux dans l’ordre. Ce n’est pas un flux de données brutes : chaque transcribe décode l’ensemble des octets reçus comme un seul fichier.

Avec MediaRecorder dans un navigateur, les morceaux d’un même enregistrement, mis bout à bout, forment un fichier WebM valide :

const ws = new WebSocket(`wss://api.lexiafrik.com/v1/ws/transcribe?api_key=${key}`);
ws.onmessage = (e) => {
  const msg = JSON.parse(e.data);
  if (msg.type === 'transcription') console.log(msg.text);
  if (msg.type === 'error') console.error(msg.detail);
};

const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const rec = new MediaRecorder(stream, { mimeType: 'audio/webm' });
rec.ondataavailable = async (e) => ws.send(await e.data.arrayBuffer());
rec.onstop = () => ws.send('transcribe');

rec.start(250);               // un morceau toutes les 250 ms
setTimeout(() => rec.stop(), 10_000);

En Python :

import asyncio, json, os, websockets

async def main():
    url = f"wss://api.lexiafrik.com/v1/ws/transcribe?api_key={os.environ['LEXIAFRIK_API_KEY']}"
    async with websockets.connect(url) as ws:
        await ws.recv()                                   # {"type": "ready"}
        with open("phrase.wav", "rb") as f:
            while chunk := f.read(64 * 1024):
                await ws.send(chunk)
        await ws.send("transcribe")
        print(json.loads(await ws.recv())["text"])

asyncio.run(main())

Limites

LimiteValeur
Mémoire tampon par session50 Mo (au-delà : message error, envoyez reset)
Durée d’audio par transcribe60 secondes environ ; au-delà, la transcription échoue
LangueLangue par défaut (wolof) ; le paramètre language n’existe pas sur cette route

Chaque transcribe réussi est décompté de votre quota (puis de votre crédit) et enregistré dans votre historique, comme une transcription ordinaire.

Au-delà de 60 secondes ?

Utilisez POST /v1/transcribe ou, pour de longs enregistrements, l’envoi direct et le job asynchrone, qui acceptent aussi le choix de la langue.