mirror of
https://github.com/myronblair/jarvis
synced 2026-06-30 17:50:23 -05:00
54 lines
1.5 KiB
PHP
54 lines
1.5 KiB
PHP
<?php
|
|
// ElevenLabs TTS proxy — keeps API key server-side, streams MP3 back to browser.
|
|
// POST body: {"text":"..."} Returns: audio/mpeg or JSON error
|
|
|
|
$text = trim((json_decode(file_get_contents('php://input'), true) ?? [])['text'] ?? '');
|
|
|
|
if (!$text) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'No text']);
|
|
exit;
|
|
}
|
|
|
|
// Cap at 400 chars to protect free-tier quota
|
|
$text = mb_substr($text, 0, 400);
|
|
|
|
if (!defined('ELEVENLABS_API_KEY') || !ELEVENLABS_API_KEY) {
|
|
http_response_code(503);
|
|
echo json_encode(['error' => 'ElevenLabs not configured']);
|
|
exit;
|
|
}
|
|
|
|
$payload = json_encode([
|
|
'text' => $text,
|
|
'model_id' => ELEVENLABS_MODEL,
|
|
'voice_settings' => ['stability' => 0.45, 'similarity_boost' => 0.80, 'style' => 0.10],
|
|
]);
|
|
|
|
$ch = curl_init('https://api.elevenlabs.io/v1/text-to-speech/' . ELEVENLABS_VOICE_ID);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_POST => true,
|
|
CURLOPT_HTTPHEADER => [
|
|
'xi-api-key: ' . ELEVENLABS_API_KEY,
|
|
'Content-Type: application/json',
|
|
'Accept: audio/mpeg',
|
|
],
|
|
CURLOPT_POSTFIELDS => $payload,
|
|
CURLOPT_TIMEOUT => 20,
|
|
CURLOPT_CONNECTTIMEOUT => 5,
|
|
]);
|
|
|
|
$audio = curl_exec($ch);
|
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
|
|
if ($code === 200 && $audio) {
|
|
header('Content-Type: audio/mpeg');
|
|
header('Cache-Control: no-store');
|
|
echo $audio;
|
|
} else {
|
|
http_response_code(502);
|
|
echo json_encode(['error' => 'ElevenLabs error', 'code' => $code]);
|
|
}
|