Skip to content
For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Primary navigation
Theme

Connect

Open a Realtime translation session. The WebSocket URL requires a model query parameter.

WebSocket wss://api.openai.com/v1/realtime/translations

Connect

import com.openai.client.okhttp.OkHttpClient;
import com.openai.core.ClientOptions;
import com.openai.core.http.HttpClient;
import com.openai.helpers.TranslationConnection;
import com.openai.helpers.TranslationWebSocketOptions;
import com.openai.models.realtime.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.Arrays;
import java.util.Base64;
import java.util.concurrent.TimeUnit;

// input.pcm: a short recording of 24 kHz, signed PCM16 little-endian mono audio.
public class Translate {
  public static void main(String[] args) throws Exception {
    long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(30);
    byte[] pcm = Files.readAllBytes(Paths.get("input.pcm"));
    if (pcm.length % 2 != 0)
      throw new IllegalArgumentException("input.pcm ends in a partial PCM16 sample");
    try (HttpClient http = OkHttpClient.builder().build()) {
      ClientOptions options = ClientOptions.builder().fromEnv().httpClient(http).build();
      try (TranslationConnection connection =
          TranslationConnection.connect(
              options,
              TranslationWebSocketOptions.builder()
                  .model("gpt-realtime-translate")
                  .sendTimeout(Duration.ofSeconds(10))
                  .build())) {
        connection.send(
            RealtimeTranslationClientEvent.ofSessionUpdate(
                RealtimeTranslationSessionUpdateEvent.builder()
                    .session(
                        RealtimeTranslationSessionUpdateRequest.builder()
                            .audio(
                                RealtimeTranslationSessionUpdateRequest.Audio.builder()
                                    .output(
                                        RealtimeTranslationSessionUpdateRequest.Audio.Output
                                            .builder()
                                            .language("es")
                                            .build())
                                    .build())
                            .build())
                    .build()));
        // Wait for the language change before sending audio.
        while (true) {
          long remaining = deadline - System.nanoTime();
          if (remaining <= 0)
            throw new java.util.concurrent.TimeoutException("Waiting for session.updated");
          RealtimeTranslationServerEvent event =
              connection.receiveAsync().get(remaining, TimeUnit.NANOSECONDS);
          if (event.isError()) throw new IllegalStateException(event.asError().error().message());
          if (event.isSessionClosed())
            throw new IllegalStateException("Closed before session.updated");
          if (event.isSessionUpdated()) break;
        }
        for (int offset = 0; offset < pcm.length; offset += 9600) {
          byte[] chunk = Arrays.copyOfRange(pcm, offset, Math.min(offset + 9600, pcm.length));
          connection.send(
              RealtimeTranslationClientEvent.ofSessionInputAudioBufferAppend(
                  RealtimeTranslationInputAudioBufferAppendEvent.builder()
                      .audio(Base64.getEncoder().encodeToString(chunk))
                      .build()));
        }
        long finishTime = deadline - System.nanoTime();
        if (finishTime <= 0)
          throw new java.util.concurrent.TimeoutException("Translation timed out");
        // finishAsync sends session.close. Read the flushed text while it finishes.
        java.util.concurrent.CompletableFuture<RealtimeTranslationSessionClosedEvent> finished =
            connection.finishAsync(Duration.ofNanos(finishTime));
        while (true) {
          long remaining = deadline - System.nanoTime();
          if (remaining <= 0)
            throw new java.util.concurrent.TimeoutException("Translation timed out");
          RealtimeTranslationServerEvent event =
              connection.receiveAsync().get(remaining, TimeUnit.NANOSECONDS);
          if (event.isError()) throw new IllegalStateException(event.asError().error().message());
          event.sessionOutputTranscriptDelta().ifPresent(delta -> System.out.print(delta.delta()));
          if (event.isSessionClosed()) {
            finished.get(remaining, TimeUnit.NANOSECONDS);
            System.out.println();
            break;
          }
        }
      } finally {
        options.close();
      }
    }
  }
}