diff --git a/resources/views/rd/cm-song/create.blade.php b/resources/views/rd/cm-song/create.blade.php
index a2bccb03..6427ef9b 100644
--- a/resources/views/rd/cm-song/create.blade.php
+++ b/resources/views/rd/cm-song/create.blade.php
@@ -141,27 +141,44 @@ class="w-full py-3.5 bg-indigo-600 hover:bg-indigo-700 disabled:bg-gray-300 disa
-
+
-
-
들어보기
-
-
+
+
+
+
+
+
+
들어보기
+
+
+
+
+
+
+
@@ -210,6 +227,9 @@ class="flex items-center gap-1.5 px-5 py-2 bg-white hover:bg-gray-50 text-gray-6
const playBtn = document.getElementById('playBtn');
const playIcon = document.getElementById('playIcon');
const playLabel = document.getElementById('playLabel');
+ const audioLoading = document.getElementById('audioLoading');
+ const audioReady = document.getElementById('audioReady');
+ const audioError = document.getElementById('audioError');
const downloadBtn = document.getElementById('downloadBtn');
const saveBtn = document.getElementById('saveBtn');
const retryBtn = document.getElementById('retryBtn');
@@ -306,7 +326,10 @@ function showState(state) {
generateBtn.innerHTML = '
나레이션 제작 중...';
showState('loading');
loadingText.textContent = 'AI가 나레이션을 작성하고 있어요...';
- audioSection.classList.add('hidden');
+ audioLoading.classList.remove('hidden');
+ audioReady.classList.add('hidden');
+ audioReady.style.display = '';
+ audioError.classList.add('hidden');
currentAudioData = null;
currentAudioMimeType = null;
currentAudioBlob = null;
@@ -340,38 +363,48 @@ function showState(state) {
showState('result');
// 2. TTS 음성 생성
- loadingText.textContent = '목소리를 녹음하고 있어요...';
- const audioRes = await fetch('{{ route("rd.cm-song.generate-audio") }}', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'X-CSRF-TOKEN': '{{ csrf_token() }}',
- },
- body: JSON.stringify({ lyrics: lyricsData.lyrics }),
- });
+ try {
+ const audioRes = await fetch('{{ route("rd.cm-song.generate-audio") }}', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-CSRF-TOKEN': '{{ csrf_token() }}',
+ },
+ body: JSON.stringify({ lyrics: lyricsData.lyrics }),
+ });
- const audioData = await audioRes.json();
- if (audioData.success && audioData.audio_data) {
- currentAudioData = audioData.audio_data;
- currentAudioMimeType = audioData.mime_type || 'audio/L16;rate=24000';
+ const audioData = await audioRes.json();
+ if (audioData.success && audioData.audio_data) {
+ currentAudioData = audioData.audio_data;
+ currentAudioMimeType = audioData.mime_type || 'audio/L16;rate=24000';
- const mimeType = currentAudioMimeType;
- let audioUrl;
+ const mimeType = currentAudioMimeType;
+ let audioUrl;
- if (mimeType.includes('L16') || mimeType.includes('pcm')) {
- const rateMatch = mimeType.match(/rate=(\d+)/);
- const rate = rateMatch ? parseInt(rateMatch[1]) : 24000;
- const pcmBytes = base64ToUint8Array(audioData.audio_data);
- currentAudioBlob = pcmToWav(pcmBytes, rate);
- audioUrl = URL.createObjectURL(currentAudioBlob);
+ if (mimeType.includes('L16') || mimeType.includes('pcm')) {
+ const rateMatch = mimeType.match(/rate=(\d+)/);
+ const rate = rateMatch ? parseInt(rateMatch[1]) : 24000;
+ const pcmBytes = base64ToUint8Array(audioData.audio_data);
+ currentAudioBlob = pcmToWav(pcmBytes, rate);
+ audioUrl = URL.createObjectURL(currentAudioBlob);
+ } else {
+ const rawBytes = base64ToUint8Array(audioData.audio_data);
+ currentAudioBlob = new Blob([rawBytes], { type: mimeType });
+ audioUrl = URL.createObjectURL(currentAudioBlob);
+ }
+
+ audioPlayer.src = audioUrl;
+ audioLoading.classList.add('hidden');
+ audioReady.classList.remove('hidden');
+ audioReady.style.display = 'flex';
} else {
- const rawBytes = base64ToUint8Array(audioData.audio_data);
- currentAudioBlob = new Blob([rawBytes], { type: mimeType });
- audioUrl = URL.createObjectURL(currentAudioBlob);
+ audioLoading.classList.add('hidden');
+ audioError.classList.remove('hidden');
}
-
- audioPlayer.src = audioUrl;
- audioSection.classList.remove('hidden');
+ } catch (audioErr) {
+ console.error('음성 생성 오류:', audioErr);
+ audioLoading.classList.add('hidden');
+ audioError.classList.remove('hidden');
}
} catch (error) {