$tts->languageOptions(), 'ttsGenders' => $tts->genderOptions(), ]); } public function generateImage(Request $request, OpenAiImageService $openAiImage): RedirectResponse { $data = $request->validate([ 'prompt' => ['required', 'string', 'max:1000'], 'aspect' => ['nullable', 'in:landscape,square,portrait'], 'image_count' => ['nullable', 'in:1,2,4,6'], ]); $aspect = $data['aspect'] ?? 'landscape'; $imageCount = (int) ($data['image_count'] ?? 1); try { $imageUrls = $openAiImage->generate($data['prompt'], $aspect, $imageCount); return redirect()->route('tools.index')->with([ 'tool_image_urls' => $imageUrls, 'tool_image_url' => $imageUrls[0] ?? null, 'tool_image_prompt' => $data['prompt'], 'tool_image_aspect' => $aspect, 'tool_image_count' => $imageCount, ]); } catch (\Throwable $e) { return redirect()->route('tools.index')->with('tool_error', $e->getMessage())->withInput(); } } public function textToVoice(Request $request, EdgeTtsService $tts): RedirectResponse { $languageKeys = implode(',', array_keys($tts->languageOptions())); $genderKeys = implode(',', array_keys($tts->genderOptions())); $data = $request->validate([ 'text' => ['required', 'string', 'max:2000'], 'language' => ['required', 'string', "in:{$languageKeys}"], 'gender' => ['required', 'string', "in:{$genderKeys}"], ]); try { $audioUrl = $tts->synthesize($data['text'], $data['language'], $data['gender']); return redirect()->route('tools.index')->with([ 'tool_audio_url' => $audioUrl, 'tool_audio_text' => $data['text'], 'tool_audio_language' => $data['language'], 'tool_audio_gender' => $data['gender'], ]); } catch (\Throwable $e) { return redirect()->route('tools.index')->with('tool_error', $e->getMessage())->withInput(); } } }