diff --git a/app/Http/Controllers/Rd/CmSongController.php b/app/Http/Controllers/Rd/CmSongController.php new file mode 100644 index 00000000..ff035123 --- /dev/null +++ b/app/Http/Controllers/Rd/CmSongController.php @@ -0,0 +1,147 @@ +baseUrl = config('services.gemini.base_url'); + $this->apiKey = config('services.gemini.api_key'); + } + + /** + * CM송 제작 페이지 + */ + public function index(Request $request): View|\Illuminate\Http\Response + { + if ($request->header('HX-Request')) { + return response('', 200)->header('HX-Redirect', route('rd.cm-song.index')); + } + + return view('rd.cm-song.index'); + } + + /** + * CM송 가사 생성 (Gemini API) + */ + public function generateLyrics(Request $request): JsonResponse + { + $request->validate([ + 'company_name' => 'required|string|max:100', + 'industry' => 'required|string|max:200', + 'mood' => 'required|string|max:50', + ]); + + $prompt = "당신은 전문 CM송 작사가입니다. 다음 정보를 바탕으로 짧고 기억에 남는 15초 분량의 라디오 CM송 가사를 작성해주세요. + +회사명: {$request->company_name} +업종/제품: {$request->industry} +분위기: {$request->mood} + +조건: +- 3~4줄로 짧게 작성 +- 운율을 살려서 작성 +- 지시문(예: (음악 소리), (밝은 목소리로)) 없이 오직 읽을 수 있는 가사 텍스트만 출력할 것."; + + try { + $response = Http::timeout(30)->post( + "{$this->baseUrl}/models/gemini-2.5-flash:generateContent?key={$this->apiKey}", + [ + 'contents' => [ + ['parts' => [['text' => $prompt]]], + ], + ] + ); + + if (! $response->successful()) { + return response()->json([ + 'success' => false, + 'error' => '가사 생성에 실패했습니다: '.$response->status(), + ], 500); + } + + $data = $response->json(); + $text = $data['candidates'][0]['content']['parts'][0]['text'] ?? ''; + + return response()->json([ + 'success' => true, + 'lyrics' => trim($text), + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'error' => '가사 생성 중 오류: '.$e->getMessage(), + ], 500); + } + } + + /** + * TTS 음성 생성 (Gemini TTS API) + */ + public function generateAudio(Request $request): JsonResponse + { + $request->validate([ + 'lyrics' => 'required|string|max:2000', + ]); + + try { + $response = Http::timeout(60)->post( + "{$this->baseUrl}/models/gemini-2.5-flash-preview-tts:generateContent?key={$this->apiKey}", + [ + 'contents' => [ + ['parts' => [['text' => $request->lyrics]]], + ], + 'generationConfig' => [ + 'responseModalities' => ['AUDIO'], + 'speechConfig' => [ + 'voiceConfig' => [ + 'prebuiltVoiceConfig' => [ + 'voiceName' => 'Kore', + ], + ], + ], + ], + ] + ); + + if (! $response->successful()) { + return response()->json([ + 'success' => false, + 'error' => '음성 생성에 실패했습니다: '.$response->status(), + ], 500); + } + + $data = $response->json(); + $inlineData = $data['candidates'][0]['content']['parts'][0]['inlineData'] ?? null; + + if (! $inlineData || empty($inlineData['data'])) { + return response()->json([ + 'success' => false, + 'error' => '음성 데이터를 받지 못했습니다.', + ], 500); + } + + return response()->json([ + 'success' => true, + 'audio_data' => $inlineData['data'], + 'mime_type' => $inlineData['mimeType'] ?? 'audio/L16;rate=24000', + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'error' => '음성 생성 중 오류: '.$e->getMessage(), + ], 500); + } + } +} diff --git a/resources/views/rd/cm-song/index.blade.php b/resources/views/rd/cm-song/index.blade.php new file mode 100644 index 00000000..889d92d0 --- /dev/null +++ b/resources/views/rd/cm-song/index.blade.php @@ -0,0 +1,348 @@ +@extends('layouts.app') + +@section('title', 'AI CM송 제작') + +@section('content') + +
정보를 입력하고 버튼을 누르면
이곳에 CM송이 나타납니다.
회사명과 업종을 입력하면 AI가 CM송 가사를 작성하고 목소리를 입혀줍니다.
+