'OpenAI API key not configured', 'debug' => [ 'env_file_exists' => file_exists($envFile), 'env_file_path' => $envFile, 'env_vars' => array_keys($_ENV), 'current_dir' => __DIR__, 'server_root' => $_SERVER['DOCUMENT_ROOT'] ?? 'unknown', 'tried_paths' => [ __DIR__ . '/../../config/.env', '/var/www/stefanzweig/dev/config/.env', $_SERVER['DOCUMENT_ROOT'] . '/../config/.env' ] ] ]); exit; } if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { http_response_code(405); echo json_encode(['error' => 'Method not allowed']); exit; } $input = json_decode(file_get_contents('php://input'), true); if (!isset($input['text']) || !isset($input['voice'])) { http_response_code(400); echo json_encode(['error' => 'Missing required parameters: text, voice']); exit; } $text = $input['text']; $voice = $input['voice']; $speed = $input['speed'] ?? 1.0; // Validate voice $validVoices = ['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer']; if (!in_array($voice, $validVoices)) { http_response_code(400); echo json_encode(['error' => 'Invalid voice']); exit; } // Check cache first $cacheDir = __DIR__ . '/../../tmp/audio_cache/'; if (!is_dir($cacheDir)) { mkdir($cacheDir, 0755, true); } $cacheKey = md5($text . $voice . $speed); $cacheFile = $cacheDir . $cacheKey . '.mp3'; if (file_exists($cacheFile)) { // Return cached audio $audioData = base64_encode(file_get_contents($cacheFile)); echo json_encode([ 'success' => true, 'audio' => $audioData, 'cached' => true ]); exit; } // Call OpenAI TTS API $url = 'https://api.openai.com/v1/audio/speech'; $data = [ 'model' => 'tts-1', 'input' => $text, 'voice' => $voice, 'speed' => $speed ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $openaiKey, 'Content-Type: application/json' ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 30); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch); curl_close($ch); if ($error) { http_response_code(500); echo json_encode(['error' => 'CURL error: ' . $error]); exit; } if ($httpCode !== 200) { http_response_code($httpCode); echo json_encode(['error' => 'OpenAI API error', 'response' => $response]); exit; } // Save to cache file_put_contents($cacheFile, $response); // Return audio data $audioData = base64_encode($response); echo json_encode([ 'success' => true, 'audio' => $audioData, 'cached' => false ]); ?>