Início → Blog → Voz para texto em Java: código no HttpClient padrão
Voz para texto em Java: código no HttpClient padrão
O Java traz um cliente HTTP nativo desde a versão 11, e isso basta: nenhuma biblioteca de terceiros é necessária para enviar áudio. O único incômodo é montar o corpo multipart à mão. Segue o código pronto para colar.
Montando a requisição multipart
import java.net.URI;
import java.net.http.*;
import java.nio.file.*;
import java.io.ByteArrayOutputStream;
String boundary = "----vs" + System.nanoTime();
Path audio = Path.of("call.ogg");
var body = new ByteArrayOutputStream();
body.write(("--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"model\"\r\n\r\nwhisper-1\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"file\"; filename=\"" + audio.getFileName() + "\"\r\n"
+ "Content-Type: audio/ogg\r\n\r\n").getBytes());
body.write(Files.readAllBytes(audio));
body.write(("\r\n--" + boundary + "--\r\n").getBytes());
var request = HttpRequest.newBuilder(URI.create("https://voicesscribe.com/v1/audio/transcriptions"))
.header("Authorization", "Bearer " + System.getenv("VS_KEY"))
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
.timeout(java.time.Duration.ofMinutes(3))
.POST(HttpRequest.BodyPublishers.ofByteArray(body.toByteArray()))
.build();
var client = HttpClient.newHttpClient();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new IllegalStateException("erro " + response.statusCode() + ": " + response.body());
}
System.out.println(response.body());
As quebras de linha nos delimitadores precisam ser retorno de carro mais avanço de linha: com uma quebra simples o servidor não consegue interpretar o corpo.
Lendo a resposta
A resposta é um JSON com o campo text. Qualquer biblioteca conhecida serve — Jackson, Gson ou o suporte nativo do seu framework:
record Transcription(String text) {}
var mapper = new com.fasterxml.jackson.databind.ObjectMapper();
var result = mapper.readValue(response.body(), Transcription.class);
System.out.println(result.text());
Se você pediu srt ou vtt, a resposta não é JSON e sim um arquivo de legenda pronto — nada a interpretar.
Sob carga
Três coisas que convém fazer desde o começo:
- Manter um HttpClient por aplicação — ele é seguro para várias threads e reaproveita conexões.
- Não ler arquivos grandes inteiros na memória: BodyPublishers.ofFile os transmite em fluxo.
- Limitar o paralelismo com um pool de threads fixo, dimensionado pelo limite de taxa do plano.
Falhas comuns
| Sintoma | Causa |
|---|---|
| 400 num arquivo válido | parte do formulário sem filename ou delimitador quebrado |
| 401 | a chave não saiu da variável de ambiente |
| 413 | arquivo acima de 25 MB — comprima ou divida |
| Corte em arquivos longos | requisição sem tempo limite definido |
Teste com as suas próprias gravações. O cadastro leva um minuto e os minutos gratuitos bastam para avaliar a qualidade.
Obter uma chave de API grátisPerguntas frequentes
Preciso de OkHttp ou Apache HttpClient?
Não necessariamente: o cliente nativo basta. O OkHttp é mais confortável porque monta o corpo multipart por você.
O exemplo roda no Java 8?
Não, o HttpClient nativo chegou no Java 11. Na versão 8 use OkHttp ou Apache HttpClient.
Como indicar o idioma do áudio?
Acrescente outra parte do formulário chamada language com o código, por exemplo pt.
Dá para transmitir o arquivo sem carregá-lo?
Dá, BodyPublishers.ofFile envia sem carregar na memória, o que importa em arquivos próximos do limite.
Leitura relacionada
- Voz para texto em C#: conectando a partir do .NET em cinco minutos — Como transcrever áudio a partir do C#: cliente oficial e versão com HttpClient puro, processamento assíncrono, tempos limite e tratamento de erros no serviço.
- Voz para texto em Go: código só com a biblioteca padrão — Como enviar áudio para transcrição a partir do Go: requisição multipart na biblioteca padrão, leitura da resposta, tempos limite, retentativas e pool de workers.
- Erros da API de transcrição e o que eles realmente significam — Explicação dos códigos de status da API: por que aparecem 401, 400, 413, 429 e 502, como corrigir cada um e quais falhas vale a pena repetir.