La traduction en temps réel vous permet d’envoyer un flux audio à une session de traduction dédiée. Vous recevez l’audio traduit et les segments de transcription au fur et à mesure que la personne parle. Utilisez cette fonctionnalité pour l’interprétation en direct, les appels multilingues, les diffusions, les réunions, les cours et les salons de visioconférence.
Utilisez gpt-realtime-translate lorsque votre application doit traduire les propos d’une personne. Si vous avez besoin d’un assistant qui répond aux questions, appelle des outils et gère une conversation, utilisez gpt-realtime-2.1 avec une session Realtime standard.
Particularités des sessions de traduction
Les sessions de traduction Realtime utilisent une architecture différente de celle des sessions d’agent vocal.
| Session d’agent vocal | Session de traduction |
|---|---|
Se connecte à /v1/realtime. |
Se connecte à /v1/realtime/translations. |
| Le modèle joue le rôle d’assistant. | Le modèle joue le rôle d’interprète. |
| Suit un cycle de conversation et de réponse. | Traduit en continu le flux audio entrant. |
| Peut appeler des outils et faire intervenir l’assistant dans la conversation. | Produit de l’audio traduit et des segments de transcription. |
Vous pouvez appeler response.create. |
Vous n’appelez pas response.create. |
Le flux audio lui-même déclenche la traduction. Continuez à envoyer l’audio, y compris les silences entre les phrases, et traitez les événements de sortie à mesure que vous les recevez.
Choisissez un protocole de transport
Utilisez WebRTC lorsque le navigateur capture ou lit l’audio. WebRTC envoie l’audio source sous forme de piste multimédia et reçoit la parole traduite sur une piste audio distante. Vous n’avez donc pas à rééchantillonner ni à lire vous-même les blocs PCM.
Utilisez les WebSockets lorsque votre serveur reçoit déjà de l’audio brut, par exemple depuis Twilio Media Streams, un flux multimédia SIP, un système d’acquisition pour la diffusion ou un processus de traitement multimédia. Avec les WebSockets, envoyez de l’audio PCM16 à 24 kHz encodé en base64 et assurez vous-même la lecture des segments audio reçus.
Créez une session WebRTC dans le navigateur
Pour une application qui s’exécute dans le navigateur, créez sur votre serveur un secret client à courte durée de validité. N’exposez pas votre clé API standard dans le navigateur.
app.post("/session", async (req, res) => {
const language = req.body.targetLanguage ?? "es";
const response = await fetch(
"https://api.openai.com/v1/realtime/translations/client_secrets",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
"Content-Type": "application/json",
"OpenAI-Safety-Identifier": "hashed-user-id",
},
body: JSON.stringify({
session: {
model: "gpt-realtime-translate",
audio: {
output: { language },
},
},
}),
}
);
res.status(response.status).json(await response.json());
});Dans le navigateur, capturez l’audio, créez une connexion pair à pair et envoyez l’offre SDP par requête POST au point de terminaison des appels de traduction.
const { value: clientSecret } = await fetch("/session", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ targetLanguage: "es" }),
}).then((response) => response.json());
const sourceStream = await navigator.mediaDevices.getUserMedia({
audio: true,
});
const pc = new RTCPeerConnection();
pc.addTrack(sourceStream.getAudioTracks()[0], sourceStream);
const translatedAudio = new Audio();
translatedAudio.autoplay = true;
pc.ontrack = ({ streams }) => {
translatedAudio.srcObject = streams[0];
};
const events = pc.createDataChannel("oai-events");
events.onmessage = ({ data }) => {
const event = JSON.parse(data);
if (event.type === "session.output_transcript.delta") {
subtitles.textContent += event.delta;
}
};
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const sdpResponse = await fetch(
"https://api.openai.com/v1/realtime/translations/calls",
{
method: "POST",
headers: {
Authorization: `Bearer ${clientSecret}`,
"Content-Type": "application/sdp",
},
body: offer.sdp,
}
);
if (!sdpResponse.ok) {
throw new Error(await sdpResponse.text());
}
await pc.setRemoteDescription({
type: "answer",
sdp: await sdpResponse.text(),
});Créez une session WebSocket
Connectez-vous au point de terminaison dédié à la traduction et précisez le modèle dans l’URL.
Avant d’exécuter cet exemple, installez ws pour Node.js, websocket-client et sounddevice pour Python, ou async-websocket pour Ruby (gem install async-websocket). Pour Java, ajoutez la dépendance Maven com.openai:openai-java:4.75.1.
Les exemples Java présentent séparément l’établissement de la connexion, la configuration de la langue et l’envoi de l’audio. Le SDK Java permet aussi de recevoir des événements et de terminer une session, mais ce guide ne fournit pas d’exemples Java pour ces étapes. Utilisez les exemples Node.js ou Python pour suivre toutes les étapes de la traduction ci-dessous.
import WebSocket from "ws";
const ws = new WebSocket(
"wss://api.openai.com/v1/realtime/translations?model=gpt-realtime-translate",
{
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
"OpenAI-Safety-Identifier": "hashed-user-id",
},
}
);En Ruby, insérez les extraits de code de configuration et d’envoi audio ci-dessous dans le bloc Async::WebSocket::Client.connect, après avoir vérifié que la session a été créée et avant la fin du bloc. Gardez la connexion ouverte pendant l’envoi de l’audio et la réception des événements de traduction.
L’exemple de connexion en Java ferme la connexion à la fin du bloc try. Les exemples Java de configuration et d’envoi audio nécessitent une connexion TranslationConnection ouverte. Gardez-la ouverte pendant l’envoi de l’audio et la réception des résultats. Avant de quitter le bloc, terminez la session et lisez tous ses événements jusqu’à session.closed inclus, comme indiqué dans la section Fermez une session WebSocket.
Configurez la langue cible une fois la connexion ouverte.
ws.on("open", () => {
ws.send(
JSON.stringify({
type: "session.update",
session: {
audio: {
output: {
language: "es",
},
},
},
})
);
});Envoyez ensuite l’audio en continu.
ws.send(
JSON.stringify({
type: "session.input_audio_buffer.append",
audio: base64Pcm16,
})
);Écoutez les événements pour recevoir l’audio traduit et les transcriptions.
ws.on("message", (data) => {
const event = JSON.parse(data.toString());
if (event.type === "session.output_audio.delta") {
playPcm16(event.delta);
}
if (event.type === "session.output_transcript.delta") {
process.stdout.write(event.delta);
}
if (event.type === "session.input_transcript.delta") {
updateSourceTranscript(event.delta);
}
});En Go, exécutez listen en parallèle de l’envoi audio. Cette fonction ferme la connexion de transport après avoir reçu session.closed.
Fermez une session WebSocket
Lorsque le flux source se termine, envoyez un événement session.close avant de fermer la connexion WebSocket. Cet événement demande au service de traiter l’audio d’entrée en attente, de transmettre les derniers segments d’audio traduit et de transcription, puis d’envoyer un événement session.closed. Seules les sessions de traduction prennent en charge l’événement session.close.
Après avoir envoyé session.close, cessez d’envoyer de l’audio et continuez à lire les événements dans votre boucle de réception habituelle jusqu’à ce que vous receviez session.closed. Si vous fermez la connexion immédiatement, vous risquez de perdre les segments de traduction que la session est encore en train de transmettre.
let translationSessionClosing = false;
let gotTranslationClosed = false;
let drainDeadline;
ws.on("close", () => {
clearTimeout(drainDeadline);
if (!gotTranslationClosed) {
console.error("Translation disconnected before final session.closed");
process.exitCode = 1;
}
});
function closeTranslationSession() {
if (translationSessionClosing) {
return;
}
translationSessionClosing = true;
// Adjust this deadline for your application's finalization requirements.
drainDeadline = setTimeout(() => {
console.error("Translation finalization timed out");
process.exitCode = 1;
ws.close();
}, 15_000);
ws.send(JSON.stringify({ type: "session.close" }));
}
// Use this in place of the earlier output handler, so audio plays only once.
ws.on("message", (data) => {
const event = JSON.parse(data.toString());
if (event.type === "session.output_audio.delta") {
playPcm16(event.delta);
}
if (event.type === "session.output_transcript.delta") {
process.stdout.write(event.delta);
}
if (event.type === "session.input_transcript.delta") {
updateSourceTranscript(event.delta);
}
if (event.type === "error") {
clearTimeout(drainDeadline);
console.error("Translation error", event.error?.code);
process.exitCode = 1;
ws.close();
}
if (event.type === "session.closed") {
clearTimeout(drainDeadline);
gotTranslationClosed = true;
ws.close();
}
});
// Call this when the source stream ends.
closeTranslationSession();Proposez une traduction en direct à un public
Utilisez ce mode de traduction pour permettre à un public d’écouter la traduction d’une intervention ou d’un flux audio unique. Il convient notamment aux diffusions en direct, aux interventions lors de conférences, aux webinaires, aux conférences de présentation des résultats financiers, aux cours magistraux et aux vidéos.
L’architecture habituelle suit ce schéma.
source audio -> translation session -> translated audio + subtitles
Créez une session de traduction par langue cible. Si un même flux en anglais doit être traduit en espagnol et en français, créez une session de l’anglais vers l’espagnol et une autre de l’anglais vers le français.
Pour une application qui permet d’écouter la traduction dans le navigateur, capturez l’audio de l’onglet avec getDisplayMedia(), transmettez-le via WebRTC et lisez la piste audio traduite reçue à distance. Pour les diffusions en production, exécutez la traduction dans un processus de traitement multimédia côté serveur et diffusez les pistes audio traduites ou les sous-titres auprès du public.
Intégrez la traduction à une conversation
Utilisez la traduction de conversation lorsque deux participants ou plus échangent dans des langues différentes, par exemple lors d’appels d’assistance ou d’appels commerciaux, de séances de tutorat ou de discussions en visioconférence.
Conservez une piste audio distincte par participant. Si vous mélangez les voix dans un seul flux, il devient plus difficile d’identifier la personne qui parle, de lui attribuer ses sous-titres et de traiter les prises de parole simultanées.
Pour un appel entre deux personnes, créez une session de traduction dans chaque sens.
Caller A audio -> translate into Caller B language -> play to Caller B
Caller B audio -> translate into Caller A language -> play to Caller A
Dans un salon de groupe, le nombre de sessions dépend du nombre de participants qui parlent et du nombre de langues cibles.
translation sessions ~= active source speaker tracks x distinct target languages
Dans les petits salons, chaque auditeur peut créer dans son navigateur une session de traduction auxiliaire pour chaque intervenant distant dont il souhaite écouter la traduction. Dans les grands salons, utilisez un participant côté serveur ou un processus de traitement multimédia côté serveur qui s’abonne une seule fois à la piste de chaque intervenant, crée une session de traduction par langue cible et rediffuse les pistes traduites.
Testez la qualité et la latence
Testez la traduction avec des enregistrements réels et faites évaluer les résultats par des personnes bilingues. Les mesures automatisées peuvent vous aider, mais certaines erreurs perceptibles par les utilisateurs leur échappent.
Vérifiez les points suivants.
- La qualité de la traduction pour chaque paire de langues
- La traduction des noms, des nombres, des dates, des montants en devises et des numéros de téléphone
- La terminologie propre au domaine
- L’alternance entre langues et les conversations qui mêlent plusieurs langues
- La prise en charge des accents, des débits de parole rapides et des prises de parole simultanées
- Le délai avant réception du premier segment audio traduit
- La latence en fin d’énoncé
- La synchronisation des sous-titres
- La stabilité de la voix
- Le comportement lors d’une reconnexion
Si votre cas d’usage exige une restitution exacte des noms ou des termes spécialisés, constituez un jeu de référence avant le lancement et examinez manuellement les cas d’échec.
Liste de vérification pour la mise en production
- Choisissez WebRTC pour les flux multimédias côté navigateur et les WebSockets pour les flux côté serveur.
- Utilisez le point de terminaison dédié
/v1/realtime/translations. - Transmettez l’audio en continu, y compris les silences entre les phrases.
- Envoyez
session.closeet attendezsession.closedavant de fermer une session WebSocket. - Conservez une piste distincte par intervenant pour la traduction de conversation.
- Utilisez une session par langue cible.
- Affichez les transcriptions dans la langue source et dans la langue cible lorsque cela est utile.
- Prévoyez des commandes pour écouter l’audio original ou traduit, afficher les sous-titres, couper le son et régler le volume.
- Indiquez lorsqu’une reconnexion est en cours, que la traduction prend du retard ou qu’elle est indisponible.
- Suivez la latence séparément de la qualité de traduction.
Guides associés
Comparez les sessions d’agent vocal, de traduction et de transcription.
Connectez les flux multimédias du navigateur à une session Realtime.
Transmettez l’audio brut via une chaîne de traitement multimédia côté serveur.
Recevez les segments de transcription au fil du flux audio en direct.