首页博客 → Java 里的语音转文字:标准 HttpClient 代码

Java 里的语音转文字:标准 HttpClient 代码

发布于 2026-08-20 · 5 分钟阅读

Java 从 11 开始自带 HTTP 客户端,上传音频不需要第三方库。唯一的麻烦是 multipart 请求体得自己拼。下面是可以直接粘的代码。

拼 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("错误 " + response.statusCode() + ": " + response.body());
}
System.out.println(response.body());

分隔符里的换行必须是回车加换行,只写一个换行服务端就解析不了请求体。

解析响应

响应是带 text 字段的 JSON,用你熟悉的任何解析库都行——Jackson、Gson 或框架自带的:

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());

如果请求的是 srt 或 vtt,返回的根本不是 JSON,而是现成的字幕文件,不用解析。

高负载下

一开始就该做的三件事:

  1. 全应用共用一个 HttpClient——它是线程安全的,还能复用连接。
  2. 大文件不要整个读进内存:BodyPublishers.ofFile 会流式发送。
  3. 用固定大小的线程池限制并发,池子大小按套餐的频率上限来。

常见故障

现象原因
正常文件返回 400表单部分缺 filename,或 boundary 写坏了
401密钥没从环境变量里取出来
413文件超过 25 MB,需要压缩或切分
长文件被掐断请求没有设置超时

用你自己的录音试一试。 注册只需一分钟,免费额度足够判断识别质量。

免费获取 API 密钥

常见问题

需要 OkHttp 或 Apache HttpClient 吗?

不一定,内置客户端就够。OkHttp 的好处是能替你拼 multipart。

Java 8 能用这段代码吗?

不能,内置 HttpClient 从 Java 11 才有。8 上请用 OkHttp 或 Apache HttpClient。

怎么指定音频语言?

再加一个名为 language 的表单部分,填语言代码,例如 zh。

能流式发送文件吗?

可以,BodyPublishers.ofFile 不会把文件读进内存,对接近上限的文件很重要。

相关阅读