Introduction
La transcription vocale en temps réel établit une connexion persistante via WebSocket (un protocole qui maintient une connexion longue entre le client et le serveur et permet de pousser des données dans les deux sens). Le flux audio entrant est reçu, transcrit et renvoyé en continu, ce qui convient aux cas d’usage vocaux sensibles à la latence. Sa différence avec la transcription de fichier STT :
Modèles disponibles :
- gpt-live-transcribe : modèle de transcription en flux, prend en charge plusieurs langues et produit le texte transcrit en temps réel au fil de l’audio entrant.
Démarrage rapide
Endpoint de connexion
intent=transcription: obligatoire, déclare qu’il s’agit d’une session de transcription.model=gpt-live-transcribe: obligatoire, le modèle est fixé au moment de la connexion par le paramètre d’URL et ne peut plus être modifié pendant la session (voir les contraintes ci-dessous).
Authentification
Lors de la poignée de main, transmettez la clé via l’en-tête HTTP standard :Exigences sur le format audio
Un seul format d’entrée est actuellement pris en charge ; convertissez votre audio avant l’envoi :- Encodage : PCM16 (entier signé 16 bits, petit-boutiste)
- Fréquence d’échantillonnage : 24000 Hz
- Canal : mono
audio/pcm@24000. Envoyer un autre format (par exemple G.711/µ-law) entraîne un rejet et la fermeture de la session.
Les sessions de transcription ne prennent pas en charge la détection d’activité vocale (turn_detection / VAD) ; elle doit être explicitement fixée à
null. Si elle est omise ou définie à une valeur autre que null, le fournisseur de modèles rejette la transcription avec invalid_value. La passerelle force turn_detection à null dans la configuration transférée, mais il reste recommandé de le définir vous-même à null côté client pour garder un comportement clair.Configuration de session (session.update)
Une fois la connexion établie, le client envoie d’abord une tramesession.update pour configurer les paramètres de transcription. Si vous n’envoyez rien, la passerelle injecte une configuration par défaut de secours avec le modèle autorisé, mais la configuration explicite est recommandée.
Paramètres de configuration
string
requis
Type de session ; fixé à
transcription pour un cas de transcription.object
requis
Format audio d’entrée, fixé à
{ "type": "audio/pcm", "rate": 24000 }.string
requis
Modèle de transcription. Il doit être identique au
model de l’URL de connexion (gpt-live-transcribe). Passer un autre modèle est considéré comme un dépassement de droits et la session sera fermée avec le code 1008.string[]
Liste des langues attendues, sous forme de tableau (par exemple
["en", "zh"]). gpt-live-transcribe utilise le pluriel languages, ce qui permet de déclarer plusieurs langues à la fois ; préciser la langue améliore la précision et réduit la latence. Le dictionnaire des valeurs figure dans Codes de langue ci-dessous.string
Écriture au singulier, un seul code ISO-639-1 (par exemple
"en"). À utiliser en alternative à languages, sans les passer tous les deux (les passer ensemble provoque un rejet avec invalid_value). L’officiel recommande le pluriel languages pour gpt-live-transcribe ; la passerelle accepte aussi le singulier language, ce qui facilite la migration depuis d’anciens codes.string
Prompt en texte libre décrivant le contexte de l’enregistrement (par exemple « appel du service client » ou « consultation médicale avec termes spécialisés »), pour aider le modèle à coller au registre. En conditions réelles, le serveur le renvoie tel quel dans
session.updated : il est bien pris en compte.string[]
Tableau de mots-indices littéraux, pour les noms de produit, sigles, noms propres et autres mots sujets à erreur (par exemple
["AiHubMix", "gpt-live-transcribe"]). Il s’agit d’un indice et non d’une sortie imposée ; mettez chaque mot dans un élément distinct et évitez d’y inclure <, > ou des retours à la ligne. En conditions réelles, il est renvoyé et pris en compte.string
Palier latence / précision ; valeurs possibles
minimal, low, medium, high, xhigh. Plus le palier est élevé, plus la précision augmente mais plus la latence croît. Attention : la passerelle accepte ce champ (sans erreur), mais en conditions réelles il n’est pas renvoyé dans session.updated ; sa prise en compte s’appuie sur la documentation officielle et n’est pas encore confirmée par le renvoi.null
requis
Détection d’activité vocale. Elle doit être
null pour une session de transcription.object
Configuration facultative de réduction de bruit, par exemple
{ "type": "near_field" } (champ proche, adapté quand le micro est près du locuteur) ou { "type": "far_field" } (champ lointain).Codes de langue (language codes)
Les valeurs delanguages / language suivent les formats ci-dessous, sensibles à la casse et limités aux formes prises en charge ; un code non pris en charge ou mal formé est rejeté par l’API realtime :
Envoi de l’audio
Découpez l’audio PCM16 en petits fragments (par exemple un fragment toutes les 100 ms), encodez-les en base64, puis envoyez-les en continu via l’événementinput_audio_buffer.append :
input_audio_buffer.commit pour marquer la fin de ce segment, ce qui déclenche la finalisation de la transcription et renvoie le résultat completed :
Réception des résultats de transcription
Le serveur pousse des événements en continu ; principaux types d’événements :event
Confirmation de la création de session et de la mise à jour de configuration.
event
Résultat de transcription incrémental ; le champ
delta est le fragment de texte nouvellement ajouté. Renvoyé au fil de la parole, adapté à l’affichage en temps réel.event
Transcription d’un segment vocal terminée ; le champ
transcript est le texte complet de ce segment.event
Événement d’erreur, contenant le code d’erreur et l’explication.
Exemple complet
Voici deux façons de procéder, au choix :- SDK officiel OpenAI (recommandé) : pas besoin d’écrire de WebSocket à la main, il suffit de pointer
websocket_base_url(le paramètre d’adresse de base WebSocket du SDK) vers la passerelle pour réutiliser la bibliothèque officielle. - websockets natif : sans SDK, échangez directement les trames selon le protocole, avec un minimum de dépendances et un diagnostic facilité.
Pourquoi la démo officielle ne passe-t-elle pas le nom de modèle, alors que nous le devons ? L’intent de transcription d’OpenAI place le modèle dans
transcription.model de session.update, et l’URL de connexion ne porte que ?intent=transcription. La passerelle AiHubMix diffère : le nom du modèle doit figurer dans l’URL de poignée de main (?model=gpt-live-transcribe), car la passerelle en a besoin dès l’instant de la poignée de main WebSocket pour choisir le fournisseur de modèles, authentifier et réserver le quota, alors que session.update n’arrive qu’après la poignée de main, trop tard. Avec le SDK, passez donc explicitement model à connect() (le SDK l’ajoutera à la query de l’URL) ; sans lui, la passerelle renvoie dès la poignée de main un 400 missing_model_parameter : connect() lève directement une exception, la connexion ne s’établit pas du tout et l’on n’atteint jamais l’étape session.update. Dans la session, transcription.model doit toujours être identique à celui de l’URL.Résultat d’exécution (test réel en production)
Voici le résultat réel de l’exemple ci-dessus exécuté sur l’environnement de productionaihubmix.com (modèle gpt-live-transcribe). La configuration comportait languages: ["en", "zh"] + prompt + keywords + delay: "low" + noise_reduction: { "type": "near_field" } :
En conditions réelles,
languages, prompt, keywords et noise_reduction sont tous renvoyés tels quels par le serveur dans session.updated, ce qui indique que la configuration est effectivement prise en compte (et pas seulement acceptée sans traitement). Le champ delay est accepté par la passerelle mais n’est pas renvoyé ; sa prise en compte s’appuie sur la documentation officielle. language (singulier) et languages (pluriel) ne peuvent être passés que l’un ou l’autre.Facturation
- Tarif unitaire :
gpt-live-transcribeest facturé à $0.017 / minute (le prix affiché en temps réel sur la page de détail du modèle fait foi). - Facturation selon la durée audio transcrite : basée sur le nombre de secondes d’audio réellement transféré au modèle de transcription, arrondi à la seconde supérieure. Par exemple, transcrire 90 secondes d’audio coûte
90 ÷ 60 × $0.017 = $0.0255. - La facturation n’est pas affectée par les aller-retours réseau ni les attentes inactives ; seul l’audio réellement soumis à la transcription est chronométré.
- Règlement au fil de l’eau : il s’agit d’une connexion longue ; les frais ne sont pas réglés en une seule fois à la fin de la session, mais déduits en temps réel par segments pendant la session. À l’établissement de la session, une réservation de quota est effectuée pour environ 1 minute d’usage (simple contrôle d’admission, pas une déduction réelle) ; pendant la session, la réservation est renouvelée par roulement toutes les 20 secondes, les frais réels sont déduits par segments selon les secondes réellement transférées, et la réservation restante est libérée à la fin de la session. Le solde disponible du compte doit donc couvrir au moins environ 1 minute d’usage pour que la session puisse s’établir.
- Dans le détail des dépenses de Usage et facturation, la remarque de chaque enregistrement de transcription en temps réel indique le « tarif à la minute » et « le nombre de secondes réellement facturées », pour faciliter la vérification enregistrement par enregistrement.

Un enregistrement de facturation de transcription en temps réel gpt-live-transcribe dans la vue Activity de Usage et facturation ; la remarque indique 7 s d'audio facturées à $0.017 / min = $0.001982, conforme au format décrit ci-dessus.
Limites et contraintes
- Durée d’une session : une connexion WebSocket dure au maximum 62 minutes ; à échéance, le serveur ferme la connexion. Pour une durée supérieure, reconnectez-vous par segments.
- Solde insuffisant : deux cas de figure. À l’établissement de la session, si le solde disponible ne couvre pas la réservation d’environ 1 minute, la poignée de main est directement refusée (HTTP 403) et la session ne s’établit pas ; pendant la session, si le solde est épuisé (détecté lors du contrôle de renouvellement toutes les 20 secondes ou de la revérification après une déduction segmentée), la connexion déjà établie est immédiatement fermée.
- Côté serveur uniquement : la connexion directe depuis le navigateur n’est pas prise en charge (l’en-tête
Originest vérifié) ; intégrez côté serveur. - Verrouillage du modèle : le modèle est fixé dans l’URL de connexion ; le changer pendant la session via
session.updateest refusé et ferme la session. - Verrouillage du format : seul
audio/pcm@24000mono est pris en charge ; les autres formats sont refusés.
Erreurs fréquentes
Dernière mise à jour : 2026-09-16