From c1619af3903a766e7eb714afe623fc6016296b04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Sun, 8 Mar 2026 14:34:44 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[sound-logo]=20Lyria=20BGM=20WebSocket?= =?UTF-8?q?=20=EB=94=94=EB=B2=84=EA=B7=B8=20=EB=A1=9C=EA=B9=85=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/views/rd/sound-logo/index.blade.php | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/resources/views/rd/sound-logo/index.blade.php b/resources/views/rd/sound-logo/index.blade.php index f72eb3d5..b02e9a48 100644 --- a/resources/views/rd/sound-logo/index.blade.php +++ b/resources/views/rd/sound-logo/index.blade.php @@ -1792,6 +1792,8 @@ function soundLogo() { // 2) WebSocket 연결 const wsUrl = cfg.ws_url + '?key=' + cfg.api_key; + console.log('[Lyria] WebSocket 연결 시작:', cfg.ws_url); + console.log('[Lyria] Model:', cfg.model, '| Prompt:', this.bgmPrompt); const ws = new WebSocket(wsUrl); this.bgmWs = ws; @@ -1799,37 +1801,46 @@ function soundLogo() { const duration = this.bgmDuration; let setupDone = false; let playStartTime = null; + let messageCount = 0; ws.onopen = () => { + console.log('[Lyria] WebSocket 연결됨, setup 전송'); this.bgmProgress = '초기화 중...'; - // Setup 메시지 전송 ws.send(JSON.stringify({ setup: { model: cfg.model } })); }; ws.onmessage = async (event) => { + messageCount++; let raw = event.data; - // Blob이면 텍스트로 변환 - if (raw instanceof Blob) { + const isBlob = raw instanceof Blob; + if (isBlob) { + console.log('[Lyria] 메시지 #' + messageCount + ': Blob (size=' + raw.size + ')'); raw = await raw.text(); } let msg; - try { msg = JSON.parse(raw); } catch { return; } + try { + msg = JSON.parse(raw); + } catch (e) { + console.warn('[Lyria] 메시지 #' + messageCount + ': JSON 파싱 실패', typeof raw, raw.substring?.(0, 200)); + return; + } + + console.log('[Lyria] 메시지 #' + messageCount + ':', Object.keys(msg).join(', ')); // Setup 완료 if (msg.setupComplete) { setupDone = true; + console.log('[Lyria] Setup 완료, 프롬프트/설정/재생 전송'); this.bgmProgress = '프롬프트 설정 중...'; - // 프롬프트 설정 ws.send(JSON.stringify({ client_content: { weightedPrompts: [{ text: this.bgmPrompt, weight: 1.0 }] } })); - // 생성 설정 ws.send(JSON.stringify({ music_generation_config: { musicGenerationConfig: { @@ -1842,7 +1853,6 @@ function soundLogo() { } })); - // 재생 시작 ws.send(JSON.stringify({ playback_control: { playbackControl: 'PLAY' } })); @@ -1857,14 +1867,27 @@ function soundLogo() { audioChunks.push(chunk.data); } } + if (audioChunks.length % 10 === 1) { + console.log('[Lyria] 오디오 청크 수신:', audioChunks.length, '개'); + } if (playStartTime) { const elapsed = ((Date.now() - playStartTime) / 1000).toFixed(0); this.bgmProgress = '음악 생성 중... ' + elapsed + '/' + duration + '초'; } } + // 에러 응답 + if (msg.error) { + console.error('[Lyria] API 에러:', JSON.stringify(msg.error)); + this.bgmError = msg.error.message || 'Lyria API 에러'; + this.bgmLoading = false; + this.toast(this.bgmError, 'error'); + ws.close(); + } + // 프롬프트 필터링 경고 if (msg.filteredPrompt) { + console.warn('[Lyria] 프롬프트 필터링됨'); this.bgmError = '프롬프트가 안전 필터에 의해 거부되었습니다.'; this.bgmLoading = false; this.toast('입력한 프롬프트가 안전 필터에 거부되었습니다.\n다른 표현으로 변경해 주세요.', 'error'); @@ -1872,13 +1895,16 @@ function soundLogo() { } }; - ws.onerror = () => { + ws.onerror = (e) => { + console.error('[Lyria] WebSocket 에러:', e); this.bgmError = 'WebSocket 연결 오류가 발생했습니다.'; this.bgmLoading = false; this.toast('배경음악 서버 연결에 실패했습니다.\n잠시 후 다시 시도해 주세요.', 'error'); }; - ws.onclose = () => { + ws.onclose = (e) => { + console.log('[Lyria] WebSocket 종료: code=' + e.code + ', reason=' + e.reason + ', wasClean=' + e.wasClean); + console.log('[Lyria] 수신 메시지: ' + messageCount + '개, 오디오 청크: ' + audioChunks.length + '개, setupDone=' + setupDone); this.bgmWs = null; if (audioChunks.length > 0 && !this.bgmError) { this.bgmProgress = '오디오 처리 중...';