首页博客 → PHP 里的语音转文字:请求、上传与报错处理

PHP 里的语音转文字:请求、上传与报错处理

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

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,必要时切成几段并行处理,再按顺序把文本拼起来。

相关阅读