首页 → 博客 → Java 里的语音转文字:标准 HttpClient 代码
Java 里的语音转文字:标准 HttpClient 代码
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,而是现成的字幕文件,不用解析。
高负载下
一开始就该做的三件事:
- 全应用共用一个 HttpClient——它是线程安全的,还能复用连接。
- 大文件不要整个读进内存:BodyPublishers.ofFile 会流式发送。
- 用固定大小的线程池限制并发,池子大小按套餐的频率上限来。
常见故障
| 现象 | 原因 |
|---|---|
| 正常文件返回 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 不会把文件读进内存,对接近上限的文件很重要。
相关阅读
- C# 里的语音转文字:五分钟接入 .NET — 在 C# 中转录音频:官方客户端与纯 HttpClient 两种写法,异步处理、超时设置,以及 .NET 服务里的错误处理。
- Go 里的语音转文字:只用标准库的可用代码 — 从 Go 发送音频转录请求:用标准库拼 multipart、解析响应、设置超时与重试,以及处理归档用的工作池。
- 转录 API 的报错分别代表什么 — 逐个解释转录接口的状态码:401、400、413、429、502 各自的原因和修法,以及哪些失败值得自动重试。