Beranda → Blog → Suara ke teks dengan PHP: permintaan, unggahan, dan galat
Suara ke teks dengan PHP: permintaan, unggahan, dan galat
PHP masih menjalankan sebagian besar web, dan kebutuhan menerima rekaman lalu mengembalikan teks muncul terus-menerus. Pustaka khusus tidak diperlukan: cURL dari paket standar sudah cukup. Berikut kode yang bekerja dan jebakan yang biasa.
cURL polos
<?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("galat $code: $response");
}
echo json_decode($response, true)["text"];
CURLFile wajib: kalau path diberikan sebagai string biasa, PHP modern mengirimnya sebagai bidang teks dan layanan menolak dengan 400.
Versi 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);
Kunci filename di sini sama wajibnya: tanpa itu server tidak bisa menentukan formatnya.
Menerima unggahan pengguna
Formulir unggah menaruh berkas di direktori sementara, dari sanalah ia dikirim:
$upload = $_FILES["audio"] ?? null;
if (!$upload || $upload["error"] !== UPLOAD_ERR_OK) {
http_response_code(400);
exit("berkas tidak terunggah");
}
if ($upload["size"] > 25 * 1024 * 1024) {
http_response_code(413);
exit("berkas lebih dari 25 MB");
}
$file = new CURLFile($upload["tmp_name"], $upload["type"], $upload["name"]);
Jangan lupa upload_max_filesize dan post_max_size di konfigurasi PHP: nilai bawaannya sering lebih kecil dari kebutuhan, dan berkasnya tidak pernah sampai ke kode Anda.
Pemrosesan massal
Perulangan bekerja untuk sebuah arsip tapi lambat. Antrean lebih baik: simpan pekerjaan di tabel dan biarkan beberapa pekerja menghabiskannya, masing-masing dengan kebijakan coba ulang untuk kegagalan sementara.
Batas waktu bawaan cURL terlalu pendek untuk rekaman panjang — setel CURLOPT_TIMEOUT setidaknya 120 detik, kalau tidak satu jam audio akan terpotong di tengah pemrosesan.
Coba dengan rekaman Anda sendiri. Pendaftaran memakan waktu satu menit, dan menit gratisnya cukup untuk menilai kualitasnya.
Ambil kunci API gratisPertanyaan yang sering diajukan
Perlukah pustaka khusus untuk PHP?
Tidak. cURL dari paket standar sudah cukup; Guzzle hanya lebih nyaman untuk unggahan paralel.
Kenapa muncul 400 saat mengirim berkas?
Paling sering berkas dikirim sebagai string alih-alih CURLFile, atau bagian multipart tanpa filename. Layanan butuh nama untuk mengenali format.
Bagaimana menaikkan batas unggahan?
Lewat upload_max_filesize dan post_max_size di php.ini. Di sisi layanan batasnya 25 MB per berkas.
Bagaimana dengan rekaman panjang?
Kompres ke opus dan bila perlu potong menjadi bagian, proses paralel, lalu sambung teksnya berurutan.
Bacaan terkait
- Suara ke teks dengan Python: dari satu berkas ke skrip yang jalan — Transkripsi Python yang berjalan dalam sepuluh menit: pemasangan, permintaan pertama, format respons, penanganan galat, dan kesalahan yang paling banyak memakan waktu.
- Suara ke teks dengan Node.js: kode siap pakai dan jebakan yang biasa — Cara mentranskrip audio dari Node.js: SDK resmi, stream dan FormData, menangani unggahan di Express, timeout dan percobaan ulang — dengan kode yang bisa langsung disalin.
- Galat API transkripsi dan apa artinya sebenarnya — Penjelasan kode status API transkripsi: mengapa muncul 401, 400, 413, 429, dan 502, cara memperbaikinya, serta kegagalan mana yang layak diulang.