|
217 | 217 | } |
218 | 218 |
|
219 | 219 | function playNextAudio() { |
| 220 | + console.log("playNextAudio 호출:", { |
| 221 | + queueLength: audioQueue.length, |
| 222 | + isPlayingAudio: isPlayingAudio |
| 223 | + }); |
| 224 | + |
220 | 225 | if (audioQueue.length === 0) { |
221 | 226 | isPlayingAudio = false; |
222 | 227 | audioPlayer.style.display = "none"; |
| 228 | + console.log("오디오 큐가 비어있음"); |
223 | 229 | return; |
224 | 230 | } |
225 | 231 | const blob = audioQueue.shift(); |
| 232 | + console.log("오디오 재생 시작:", { |
| 233 | + blobSize: blob.size, |
| 234 | + blobType: blob.type |
| 235 | + }); |
| 236 | + |
226 | 237 | audioPlayer.src = URL.createObjectURL(blob); |
227 | 238 | audioPlayer.style.display = ""; |
228 | 239 | isPlayingAudio = true; |
229 | | - audioPlayer.play(); |
230 | | - appendLog(`<i>[오디오 재생]</i>`); |
| 240 | + |
| 241 | + const playPromise = audioPlayer.play(); |
| 242 | + if (playPromise !== undefined) { |
| 243 | + playPromise.then(() => { |
| 244 | + console.log("오디오 재생 성공"); |
| 245 | + appendLog(`<i>[오디오 재생]</i>`); |
| 246 | + }).catch(error => { |
| 247 | + console.error("오디오 재생 실패:", error); |
| 248 | + appendLog(`<i>[오디오 재생 실패: ${error.message}]</i>`); |
| 249 | + }); |
| 250 | + } |
231 | 251 | } |
232 | 252 |
|
233 | 253 | audioPlayer.onended = () => playNextAudio(); |
|
258 | 278 | console.log(`메시지 타입: ${data.type}`); |
259 | 279 |
|
260 | 280 | // 세션 ID 처리 |
261 | | - if (data.type === "session_id") { |
| 281 | + if (data.type === "session" || data.type === "session_id") { |
262 | 282 | sessionId = data.data.session_id; |
263 | 283 | appendLog(`<b>[세션 ID: ${sessionId}]</b>`); |
264 | 284 | return; |
|
274 | 294 | messageText += `<b>AI:</b> ${chatData.text}`; |
275 | 295 | } |
276 | 296 |
|
277 | | - // 오디오 데이터가 있는 경우 |
278 | | - if (chatData.audioData) { |
| 297 | + // 오디오 데이터가 있는 경우 |
| 298 | + if (chatData.audio_data) { |
279 | 299 | try { |
| 300 | + console.log("오디오 데이터 수신:", { |
| 301 | + audioDataLength: chatData.audio_data.length, |
| 302 | + audioFormat: chatData.audio_format, |
| 303 | + hasAudioData: !!chatData.audio_data |
| 304 | + }); |
| 305 | + |
280 | 306 | // Base64 디코딩 |
281 | | - const audioBytes = atob(chatData.audioData); |
| 307 | + const audioBytes = atob(chatData.audio_data); |
282 | 308 | const audioArray = new Uint8Array(audioBytes.length); |
283 | 309 | for (let i = 0; i < audioBytes.length; i++) { |
284 | 310 | audioArray[i] = audioBytes.charCodeAt(i); |
285 | 311 | } |
286 | 312 |
|
287 | | - const blob = new Blob([audioArray], { type: `audio/${chatData.audioFormat || 'wav'}` }); |
| 313 | + console.log("오디오 배열 생성:", { |
| 314 | + arrayLength: audioArray.length, |
| 315 | + blobType: chatData.audio_format || 'audio/wav' |
| 316 | + }); |
| 317 | + |
| 318 | + const blob = new Blob([audioArray], { type: `audio/${chatData.audio_format || 'wav'}` }); |
| 319 | + console.log("Blob 생성 완료:", { |
| 320 | + blobSize: blob.size, |
| 321 | + blobType: blob.type |
| 322 | + }); |
| 323 | + |
288 | 324 | audioQueue.push(blob); |
289 | 325 | if (!isPlayingAudio) playNextAudio(); |
290 | 326 |
|
|
313 | 349 | } |
314 | 350 |
|
315 | 351 | // 하위 호환성을 위한 기존 구조 처리 |
316 | | - if (data.type === "session_id") { |
| 352 | + if (data.type === "session" || data.type === "session_id") { |
317 | 353 | sessionId = data.session_id; |
318 | 354 | appendLog(`<b>[세션 ID: ${sessionId}]</b>`); |
319 | 355 | return; |
|
328 | 364 | } |
329 | 365 |
|
330 | 366 | // 오디오 데이터가 있는 경우 |
331 | | - if (data.audioData) { |
| 367 | + if (data.audio_data) { |
332 | 368 | try { |
333 | 369 | // Base64 디코딩 |
334 | | - const audioBytes = atob(data.audioData); |
| 370 | + const audioBytes = atob(data.audio_data); |
335 | 371 | const audioArray = new Uint8Array(audioBytes.length); |
336 | 372 | for (let i = 0; i < audioBytes.length; i++) { |
337 | 373 | audioArray[i] = audioBytes.charCodeAt(i); |
338 | 374 | } |
339 | 375 |
|
340 | | - const blob = new Blob([audioArray], { type: `audio/${data.audioFormat || 'wav'}` }); |
| 376 | + const blob = new Blob([audioArray], { type: data.audio_format || 'audio/wav' }); |
341 | 377 | audioQueue.push(blob); |
342 | 378 | if (!isPlayingAudio) playNextAudio(); |
343 | 379 |
|
|
368 | 404 | } |
369 | 405 | } else if (event.data instanceof ArrayBuffer) { |
370 | 406 | // 바이너리 메시지 처리 |
| 407 | + console.log("바이너리 메시지 수신:", { |
| 408 | + dataLength: event.data.byteLength, |
| 409 | + dataType: typeof event.data |
| 410 | + }); |
| 411 | + |
371 | 412 | try { |
372 | 413 | // 바이너리 프로토콜 파싱 시도 |
373 | 414 | const result = parseBinaryMessage(event.data); |
|
0 commit comments