| namespace App\Http\Controllers; | |
| use App\Services\EdgeTtsService; | |
| use App\Services\OpenAiImageService; | |
| use Illuminate\Http\RedirectResponse; | |
| use Illuminate\Http\Request; | |
| use Illuminate\View\View; | |
| class AiToolsController extends Controller | |
| { | |
| public function index(EdgeTtsService $tts): View | |
| { | |
| return view('tools.index', [ | |
| 'ttsLanguages' => $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(); | |
| } | |
| } | |
| } | |