La traducción en tiempo real te permite enviar el audio original de forma continua a una sesión dedicada a la traducción y recibir el audio traducido y fragmentos de la transcripción mientras la persona sigue hablando. Úsala para interpretación en vivo, llamadas multilingües, transmisiones, reuniones, clases y salas de videollamada.
Usa gpt-realtime-translate cuando tu aplicación deba traducir lo que dice una persona. Si necesitas un asistente que responda preguntas, invoque herramientas y gestione una conversación, usa gpt-realtime-2.1 con una sesión estándar de Realtime.
Diferencias entre las sesiones de traducción y las de agentes de voz
Las sesiones de traducción de Realtime tienen una arquitectura distinta a la de las sesiones de agentes de voz.
| Sesión de agente de voz | Sesión de traducción |
|---|---|
Se conecta a /v1/realtime. |
Se conecta a /v1/realtime/translations. |
| El modelo actúa como asistente. | El modelo actúa como intérprete. |
| Gestiona el ciclo de vida de la conversación y de las respuestas. | Traduce de forma continua a medida que recibe audio. |
| Puede invocar herramientas y generar intervenciones del asistente. | Genera audio traducido y fragmentos de la transcripción. |
Puedes llamar a response.create. |
No llamas a response.create. |
La traducción comienza con el propio flujo de audio. Sigue enviando audio, incluidos los silencios entre frases, y procesa los eventos de salida a medida que lleguen.
Elegir un protocolo de transporte
Usa WebRTC cuando el navegador capture o reproduzca audio. WebRTC envía el audio original como una pista multimedia y recibe la voz traducida como una pista de audio remota. Así evitas tener que remuestrear o reproducir manualmente los fragmentos de audio PCM.
Usa WebSockets cuando tu servidor ya reciba audio sin procesar, por ejemplo, de Twilio Media Streams, de flujos multimedia SIP, de un sistema de recepción de transmisiones o de un proceso multimedia. Con WebSockets, envía audio PCM16 a 24 kHz codificado en base64 y encárgate de reproducir los fragmentos de audio que recibas.
Crear una sesión WebRTC en el navegador
Para las aplicaciones que se ejecutan en el navegador, crea en tu servidor un secreto de cliente de corta duración. No expongas tu clave de API estándar en el navegador.
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());
});En el navegador, captura el audio, crea una conexión entre pares y envía la oferta SDP mediante una solicitud POST al punto de acceso para llamadas de traducción.
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(),
});Crear una sesión WebSocket
Conéctate al punto de acceso dedicado a la traducción y selecciona el modelo en la URL.
Antes de ejecutar este ejemplo, instala ws para Node.js, websocket-client y sounddevice para Python o async-websocket para Ruby (gem install async-websocket). Para Java, agrega la dependencia de Maven com.openai:openai-java:4.75.1.
Los ejemplos de Java muestran por separado cómo establecer la conexión, configurar el idioma y enviar el audio de entrada. El SDK de Java permite recibir eventos y finalizar una sesión, pero esta guía no incluye ejemplos de Java para esos pasos. Para seguir el flujo de traducción completo que se describe a continuación, usa los ejemplos de Node.js o Python.
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, inserta los siguientes fragmentos de código para configurar el idioma y agregar audio dentro del bloque Async::WebSocket::Client.connect, después de comprobar que se creó la sesión y antes de que termine el bloque. Mantén abierta la conexión mientras envías audio y recibes eventos de traducción.
El ejemplo de conexión en Java cierra el socket cuando termina el bloque try. Los ejemplos de configuración y entrada de audio en Java requieren una TranslationConnection abierta. Mantenla abierta mientras envías audio y recibes la salida. Antes de salir del bloque, finaliza la sesión y lee todos sus eventos hasta recibir session.closed, como se describe en Cerrar una sesión WebSocket.
Configura el idioma de destino una vez que se abra el socket.
ws.on("open", () => {
ws.send(
JSON.stringify({
type: "session.update",
session: {
audio: {
output: {
language: "es",
},
},
},
})
);
});Luego, agrega audio de forma continua.
ws.send(
JSON.stringify({
type: "session.input_audio_buffer.append",
audio: base64Pcm16,
})
);Escucha los eventos que contienen el audio traducido y las transcripciones.
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, ejecuta listen en paralelo con el envío de audio. Esta función cierra la conexión de transporte después de recibir session.closed.
Cerrar una sesión WebSocket
Cuando termine el flujo de audio original, envía un evento session.close antes de cerrar el WebSocket. El evento le indica al servicio que procese el audio de entrada pendiente, emita el audio traducido y la transcripción que queden por enviar y luego envíe un evento session.closed. El evento session.close solo se admite en las sesiones de traducción.
Después de enviar session.close, deja de agregar audio y sigue leyendo eventos en tu bucle habitual de recepción hasta que recibas session.closed. Si cierras el socket de inmediato, puedes perder parte de la traducción que la sesión aún está enviando.
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();Implementar la traducción para una audiencia
Usa esta modalidad cuando necesites traducir para una audiencia el audio de una sola persona o de una sola transmisión. Algunos ejemplos son las transmisiones en vivo, las ponencias en conferencias, los seminarios web, las llamadas de presentación de resultados financieros, las clases y los videos.
Esta es la arquitectura habitual.
source audio -> translation session -> translated audio + subtitles
Crea una sesión de traducción por cada idioma de destino. Si necesitas traducir el mismo audio en inglés al español y al francés, crea una sesión de inglés a español y otra de inglés a francés.
En las aplicaciones de navegador que ofrecen traducción para una audiencia, captura el audio de la pestaña con getDisplayMedia(), envíalo por WebRTC y reproduce la pista remota de audio traducido. Para transmisiones en producción, ejecuta la traducción en un proceso multimedia del servidor y publica pistas de audio traducidas o subtítulos para la audiencia.
Implementar la traducción de conversaciones
Usa la traducción de conversaciones cuando dos o más participantes se comuniquen en distintos idiomas. Algunos ejemplos son las llamadas de soporte o de ventas, las tutorías y las salas de videollamada.
Mantén separadas las pistas de audio de los participantes. Mezclar las voces en un solo flujo dificulta identificar a cada persona, asignarle los subtítulos que le corresponden y procesar el audio cuando varias personas hablan a la vez.
Para una llamada entre dos personas, crea una sesión de traducción para cada sentido.
Caller A audio -> translate into Caller B language -> play to Caller B
Caller B audio -> translate into Caller A language -> play to Caller A
En las salas grupales, la cantidad de sesiones depende de cuántas personas estén hablando y de los idiomas de destino.
translation sessions ~= active source speaker tracks x distinct target languages
En salas pequeñas, cada oyente puede crear en su navegador procesos auxiliares de traducción para los participantes remotos a quienes quiera escuchar en su idioma. En salas más grandes, usa un participante o un proceso multimedia que se ejecute en el servidor, se suscriba una sola vez a la pista de cada persona que habla, cree una sesión de traducción por idioma de destino y vuelva a publicar las pistas traducidas.
Evaluar la calidad y la latencia
Prueba la traducción con audio real y pide a personas bilingües que la revisen. Las métricas automatizadas pueden ayudar, pero hay errores que los usuarios notarán aunque las métricas no los detecten.
Evalúa los siguientes aspectos.
- La calidad de la traducción para cada par de idiomas.
- La traducción de nombres, números, fechas, monedas y números de teléfono.
- El manejo de la terminología especializada.
- Los cambios de idioma y las conversaciones en las que se mezclan idiomas.
- El manejo de acentos, del habla rápida y de voces que se superponen.
- La latencia hasta recibir el primer fragmento de audio traducido.
- La latencia al final de cada intervención.
- La sincronización de los subtítulos.
- La consistencia de la voz.
- El comportamiento durante la reconexión.
Si tu caso de uso exige reproducir con exactitud los nombres o los términos especializados, prepara un conjunto de pruebas de referencia antes del lanzamiento y revisa los errores manualmente.
Lista de verificación para producción
- Elige WebRTC para los flujos multimedia del navegador y WebSockets para los del servidor.
- Usa el punto de acceso dedicado
/v1/realtime/translations. - Transmite audio de forma continua, incluidos los silencios entre frases.
- Usa
session.closey espera a recibirsession.closedantes de cerrar una sesión WebSocket. - Mantén separadas las pistas de cada participante al traducir conversaciones.
- Usa una sesión por idioma de destino.
- Muestra tanto la transcripción original como la traducida cuando sea útil.
- Ofrece controles para el audio original, el audio traducido, los subtítulos, el silencio y el volumen.
- Indica cuándo hay una reconexión en curso, un retraso o falta de disponibilidad.
- Mide la latencia por separado de la calidad de la traducción.
Guías relacionadas
Compara las sesiones de agentes de voz, de traducción y de transcripción.
Conecta los flujos multimedia del navegador a una sesión en tiempo real.
Transmite audio sin procesar mediante un flujo de procesamiento multimedia en el servidor.
Transmite fragmentos de la transcripción a medida que se recibe el audio en vivo.