首页 → 博客 → PHP 里的语音转文字:请求、上传与报错处理
PHP 里的语音转文字:请求、上传与报错处理
PHP 依旧撑着大量网站,接收录音并返回文本的需求随处可见。不需要专门的库,标准发行版里的 cURL 就够。下面是可用的代码和常踩的坑。
原生 cURL
<?php
$ch = curl_init("https://voicesscribe.com/v1/audio/transcriptions");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("VS_KEY")],
CURLOPT_POSTFIELDS => [
"model" => "whisper-1",
"file" => new CURLFile("call.ogg", "audio/ogg", "call.ogg"),
],
]);
$response = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code !== 200) {
throw new RuntimeException("错误 $code: $response");
}
echo json_decode($response, true)["text"];
CURLFile 是必须的:直接传路径字符串的话,新版 PHP 会把它当普通文本字段发出去,服务端返回 400。
Guzzle 写法
$client = new GuzzleHttp\Client(["base_uri" => "https://voicesscribe.com/v1/"]);
$response = $client->post("audio/transcriptions", [
"headers" => ["Authorization" => "Bearer " . getenv("VS_KEY")],
"multipart" => [
["name" => "model", "contents" => "whisper-1"],
["name" => "file", "contents" => fopen("call.ogg", "r"), "filename" => "call.ogg"],
["name" => "response_format", "contents" => "verbose_json"],
],
]);
$data = json_decode((string) $response->getBody(), true);
这里的 filename 同样必填,没有它服务端判断不出格式。
接收用户上传
上传表单会把文件放进临时目录,从那里直接发出去:
$upload = $_FILES["audio"] ?? null;
if (!$upload || $upload["error"] !== UPLOAD_ERR_OK) {
http_response_code(400);
exit("没有收到文件");
}
if ($upload["size"] > 25 * 1024 * 1024) {
http_response_code(413);
exit("文件超过 25 MB");
}
$file = new CURLFile($upload["tmp_name"], $upload["type"], $upload["name"]);
别忘了 PHP 配置里的 upload_max_filesize 和 post_max_size:默认值经常偏小,文件根本到不了你的代码。
批量处理
循环能跑通一个归档,但很慢。更好的做法是队列:任务写进表里,由多个工作进程分头消费,各自带上临时错误的重试。
cURL 的默认超时对长录音太短——把 CURLOPT_TIMEOUT 设到至少 120 秒,否则一小时的音频会在处理中途被掐断。
用你自己的录音试一试。 注册只需一分钟,免费额度足够判断识别质量。
免费获取 API 密钥常见问题
PHP 需要专门的库吗?
不需要。标准发行版的 cURL 足够,Guzzle 只是并发上传时更顺手。
发文件为什么返回 400?
多半是把文件当字符串传了,或者 multipart 里没给 filename。服务端需要文件名来判断格式。
怎么提高上传上限?
改 php.ini 里的 upload_max_filesize 和 post_max_size。服务端这边的上限是单文件 25 MB。
长录音怎么办?
压成 opus,必要时切成几段并行处理,再按顺序把文本拼起来。
相关阅读
- Python 语音转文字:从一个文件到可用脚本 — 十分钟搭好 Python 语音转文字:安装、第一个请求、响应格式怎么选、错误处理与并发加速,以及最浪费时间的几个坑。
- Node.js 语音转文字:能直接用的代码和那些坑 — 在 Node.js 里转录音频:官方 SDK、流与 FormData、Express 上传处理、超时与重试——全部是可以直接粘贴的代码。
- 转录 API 的报错分别代表什么 — 逐个解释转录接口的状态码:401、400、413、429、502 各自的原因和修法,以及哪些失败值得自动重试。